Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Detect UITabBar Selected Index/ Item Changes that is set Programmatically

I would like to know how do we detect when the selected TabBar Item or Index is changed when the changes is done programmatically?

self.tabBarController.selectedIndex = 1;

This two delegate function only detect changes when the tabBar Item was selected by user. It does not fire when the changes to the selectedIndex was done programmatically.

func tabBarController(tabBarController: UITabBarController, didSelectViewController viewController: UIViewController) {
    println("tabBarController didSelectViewController")
}

override func tabBar(tabBar: UITabBar, didSelectItem item: UITabBarItem!) {
    println("tabBar didSelectItem")
}
like image 336
JayVDiyk Avatar asked Jun 07 '15 09:06

JayVDiyk


4 Answers

Along all answers here, if you subclassed UITabBarController already, here's a simple solution for all tab bar changes (User initiated and programmatic ):

// Override selectedViewController for User initiated changes
override var selectedViewController: UIViewController? {
    didSet {
        tabChangedTo(selectedIndex: selectedIndex)
    }
}
// Override selectedIndex for Programmatic changes    
override var selectedIndex: Int {
    didSet {
        tabChangedTo(selectedIndex: selectedIndex)
    }
}

// handle new selection
 func tabChangedTo(selectedIndex: Int) {}
like image 131
Meseery Avatar answered Oct 22 '22 16:10

Meseery


Previous answers are sufficient to "detect" the changes, however it does not detect which index is being pressed.

func selectItemWithIndex(value: Int) {
    self.tabBarControllertabBarController.selectedIndex = value;
    self.tabBar(self.tabBar, didSelectItem: (self.tabBar.items as! [UITabBarItem])[value]);
}

self.selectedIndex will not return the selected index right away. To check which item is being pressed, we would need to compare the item with the tabBarItems in our UITabBarController

override func tabBar(tabBar: UITabBar, didSelectItem item: UITabBarItem!) {
    if item == (self.tabBar.items as! [UITabBarItem])[0]{ 
       //Do something if index is 0
    }
    else if item == (self.tabBar.items as! [UITabBarItem])[1]{
       //Do something if index is 1
    }
}
like image 21
Eddy Liu Avatar answered Oct 22 '22 15:10

Eddy Liu


In swift, you can do it by overriding selectedIndex property of UITabBarController.

First subclass UITabBarController and add all the following code.

//Overriding this to get callback whenever its value is changes
   override var selectedIndex: Int {
      didSet {
         handleTabSelection(selectedIndex: selectedIndex)
      }
   }

Also add this delegate method of UITabBarControllerDelegate

func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) {
    //Tab tapped
    guard let viewControllers = tabBarController.viewControllers else { return }
    let tappedIndex = viewControllers.index(of: viewController)! 
    //Tab tapped at tappedIndex
    handleTabSelection(selectedIndex: tappedIndex)
}

Finally, we call this method from both places so that all the cases are handled.

private func handleTabSelection(selectedIndex: Int) {
    //Do something on tab selection at selectedIndex
}
like image 5
Vineet Ashtekar Avatar answered Oct 22 '22 14:10

Vineet Ashtekar


Swift 3

Here's a somewhat safer Swift-3 version, of what's been proposed above:

func selectItem(withIndex index: Int) {

    if  let controller = tabBarController,
        let tabBar = tabBarController?.tabBar,
        let items = tabBarController?.tabBar.items
    {
        guard index < items.count else { return }

        controller.selectedIndex = index
        controller.tabBar(tabBar, didSelect: items[index])
    }
}

UITabBarController:

override func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) {
    if let items = tabBar.items {
        items.enumerated().forEach { if $1 == item { print("your index is: \($0)") } }
    }
}

Usage:

selectItem(withIndex: 1)
like image 2
ziligy Avatar answered Oct 22 '22 14:10

ziligy