How to detect tab bar index changes in swift? - swift

I have 3 tabs in a Tab Bar Controller: Main, TabOne, TabTwo(tab index 0,1,2 respectively)
Main view controller has a table view will show all the elements in a an array. In view controllers TabOne and TabTwo, they all have buttons:
#IBAction func mypost(_ sender: Any) {
tabBarController?.selectedIndex = 0}
The array in Main view controller should be changed differently based on the tab index of the previous view controller. Ex.
If the previous view controller is TabTwo, then the table view will only show all the elements of even indices
BUT
If the previous view controller is TabOne, then the table view will only show all the elements of odd indices
How can I do it?

One possible solution is to have your main view controller set itself up as the delegate of the tab bar controller. Then implement the delegate method shouldSelect and look at the tab controller's currently selected index.
func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool
let index = tabBarController.selectedIndex
if index == 1 {
// load data appropriate for coming from the 2nd tab
} else index == 2 {
// load data appropriate for coming from the 3rd tab
}
return true
}

Related

Unable to retain the selected rows when navigating the UIVIewControllers in swift

I have two uiviewcontrollers for filter purpose, from the first controller using the button i could present the second view controller, from the second view controller i have a tableview and select their rows and passing those row values to the first view controller. It passes the values good, but i again click the same button of the first controller, like wise previous it opens the second controller but the rows i already selected seem unselected.
sample code: for clicking the First controller button for opening the view controller
#objc func empFilterButton(_ sender: Any){
let controller = EmployeeFilterViewController()
self.navigationController?.pushViewController(controller, animated: true)
}
sample code: for selecting the rows and pass those values to first view controller
#objc func applyFilter(_ sender: Any){
let empViewCtrl = EmployeeViewController()
empViewCtrl.deptIdString = deptIdString
empViewCtrl.dateIdString = dateIdString
empViewCtrl.shiftIdString = shiftIdString
empViewCtrl.locationIdString = locationIdString
self.navigationController?.pushViewController(empViewCtrl, animated: true)
}

Tab Bar Controller index changing?

I have 2 tabs : Calc VC and Browse VC; they are in that order and the app starts on Calc VC.
Using a print statement tabbarcontroller.selectedindex in viewwillappear of each VCs I learned that when Calc VC first appear, it shows an index of 0. When I tap on Browse VC, it shows an index of 1. So far so good.
When I tap on Calc VC, its index becomes 1 and Browse VC becomes 0. It remains like that until you quit the app.
Why it's an issue? I'm trying to disable Browse VC when Calc VC is active by using .isEnabled = false but I can't do it that way because of the changing index
At the time of viewWillAppear triggered, selectedIndex might not be changed. You should use viewDidAppear.
override func viewDidAppear(_ animated: Bool) {
print(tabBarController?.selectedIndex)
}
Or you can use tabBar(_:didSelect:) of UITabBarDelegate
override func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) {
print(tabBar.items?.index(of: item))
}

Segueing to a single view controller that will display some number of UITextFields depending on index selected in table view controller

In my current application, I have a UITableViewController that allows me to segue to three different indices depending on the row selected. If I select row one, I segue to a view controller with three UITextFields. If I select row two, I segue to a NEW view controller with one UITextField. If I select row three, I segue to ANOTHER NEW view controller with five UITextFields. I am looking for a way to condensing the view controllers I am going to into one view controller that will dynamically hide/unhide or remove/add the needed number of UITextFields depending on the index selected in the table view controller. I need the text fields to display in a vertical stack view.
Although it would be very valuable, I am not looking for a solution/example from someone, but rather letting me know some topics I can research would be extremely helpful.
Thank you for your time,
Tony
There might be different approaches for this problem, but I would create a stackView in the NEW view controller with the maximum possible number of textFields embedded. Lets say the VC with most textFields can contain 3 textFields. Create your stackView with 3 textFields inside.
Then segue the indexPath.row of tableView to the NEW VC, it can hold a variable of Integer like:
var index: Int?
In didSelectRowAt method of tableView:
performSegue(withIdentifier: "yourIdentifier", sender: indexPath.row)
In prepareForSegue method:
if segue.identifier == "yourIdentifier"
let vc = segue.destination as! NEWViewController
vc.index = sender
Set tag to your textFields in your NEW View controller, so you can know which textField you will want to delete depending on index.
Then in viewDidLoad of your newViewController, you can remove textFields from your stackView according to the index (Then you might run into which ):
var counter = 0
while counter < index {
answerStackView.subviews.forEach { (view) in
if counter < index {
if view is UITextField {
if view.tag == /*something here to delete specific textFields depending on index. */ {
view.removeFromSuperview()
}
}
}
counter += 1
}
}

Segue removes tabBarItem.badgeValue

I have a custom TabBarControllerand on one of the Tab Bar Items I have a round red counter. The first Tab Tab Item presents a summary View Controller. The second Tab Bar Item presents a menu embedded in a Navigation Controller The Tab Bar Counterworks fine across the board, except when I segue back from the summary View Controller. Then the counter disappears. I have tried to load the counter in the customTabBarController:
import UIKit
class CustomTabBarController: UITabBarController {
override func viewDidAppear(_ animated: Bool) {
if tabBarCounter != 0
{
let vc = self.tabBarController?.viewControllers?.last
vc?.tabBarItem.badgeValue = "\(tabBarCounter)"
vc?.tabBarItem.badgeColor = UIColor.red
}
}
}
Screendump of storyboard. (The bottom ViewController is the one I´m having trouble with. Segue highlited)

Swift - Selected tab bar index not triggering scroll to top

I have a tab bar with five items, and I am trying to add a functionality to scroll to the top when the user taps the tab bar item again. Added the UITabBarControllerDelegate to the views where I want to trigger the event and also created a function to determine the selected tab bar index.
When I open the app, index 0 is auto-selected and works perfectly. The view auto scrolls to the top when I scroll down and tap the tab bar index. The problem occurs when I go to index 1 and trigger the scroll there. It somehow completely removes the auto-scroll from my first tab bar item.
Selecting other tab bar items without the auto scroll does not affect index 0 at all.
Home (index 0)
func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) {
let tabBarIndex = tabBarController.selectedIndex
if tabBarIndex == 0 {
self.collectionView?.setContentOffset(CGPoint(x: 0, y: -10), animated: true)
}
}
Users (index 1)
func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) {
let tabBarIndex = tabBarController.selectedIndex
if tabBarIndex == 1 {
self.tableView?.setContentOffset(CGPoint(x: 0, y: 0), animated: true)
}
}
Anything with a delegate property can only have one delegate assigned to it at any given time. What ever set the delegate most recently will receive the next delegate method call.
In your case you can probably reset the tab controller's delegate to self in each view controller's viewDidAppear method since you want the currently visible view controller to be the current tab controller delegate.
Add the following to each view controller that needs to be the tab controller's delegate:
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
self.tabBarController?.delegate = self
}