Detect UITabBar Selected Index/ Item Changes that is set Programmatically

两盒软妹~` 提交于 2019-12-18 05:39:06

问题


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")
}

回答1:


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
    }
}



回答2:


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) {}



回答3:


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
}



回答4:


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)



回答5:


that can't be done but some kind of hacking it can be done and i am sure that's gonna be a temporary solution for this problem. override below method for tabbarcontrollerdelegate do your stuff inside this is called when tab is switched in either way programatically or tapping on tab bar item.

func tabBarController(_ tabBarController: UITabBarController, animationControllerForTransitionFrom fromVC: UIViewController, to toVC: UIViewController) -> UIViewControllerAnimatedTransitioning?
{
    toVC.tabBarItem.setTitleTextAttributes([NSFontAttributeName: UIFont.fontFuturaMedium11, NSForegroundColorAttributeName: UIColor.colorAppThemeColor], for: .normal)
    fromVC.tabBarItem.setTitleTextAttributes([NSFontAttributeName: UIFont.fontFuturaBTBook11, NSForegroundColorAttributeName: UIColor.colorStudentTabText], for: .normal)
    return nil
}



回答6:


I've found a lovely solution to this. Thanks to Ckouta for the idea.

I simply create a function to change the index and fire the delegate protocol of UITabBar's didSelectItem

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

Usage

    selectItemWithIndex(1);



回答7:


I only cared about the selectedIndex in one of the VCs in the tab bar controller stack. So I KVO:ed segmentedIndex on the tabbarcontroller instance from that VC. Works well, no real problems.




回答8:


Swift 4:- You have to use these lines of code for detecting UITabBar selected item index.

func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) {

    if item == (tabBar.items)![0] {
        // do something with 1st tab
    }
    else if item == (tabBar.items)![1] {
        // do something with 2nd tab
    }
}


来源:https://stackoverflow.com/questions/30692206/detect-uitabbar-selected-index-item-changes-that-is-set-programmatically

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!