Ios 检测以编程方式设置的UITabBar选定索引/项更改

Ios 检测以编程方式设置的UITabBar选定索引/项更改,ios,uitabbarcontroller,uitabbar,uitabbaritem,Ios,Uitabbarcontroller,Uitabbar,Uitabbaritem,我想知道,当以编程方式进行更改时,我们如何检测所选选项卡项或索引何时更改 self.tabBarController.selectedIndex = 1; 此两个代理函数仅在用户选择tabBar项时检测更改。当以编程方式更改selectedIndex时,它不会激发 func tabBarController(tabBarController: UITabBarController, didSelectViewController viewController: UIViewController

我想知道,当以编程方式进行更改时,我们如何检测所选选项卡项或索引何时更改

self.tabBarController.selectedIndex = 1;
此两个代理函数仅在用户选择tabBar项时检测更改。当以编程方式更改selectedIndex时,它不会激发

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

override func tabBar(tabBar: UITabBar, didSelectItem item: UITabBarItem!) {
    println("tabBar didSelectItem")
}

我找到了一个很好的解决办法。多亏了库塔的主意

我只需创建一个函数来更改索引并触发UITabBar的didSelectItem的委托协议

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


先前的答案足以“检测”更改,但它无法检测正在按下的索引

func selectItemWithIndex(value: Int) {
    self.tabBarControllertabBarController.selectedIndex = value;
    self.tabBar(self.tabBar, didSelectItem: (self.tabBar.items as! [UITabBarItem])[value]);
}
self.selectedIndex不会立即返回所选索引。要检查正在按下的项目,我们需要将该项目与UITabBarController中的tabBarItems进行比较


这是不可能做到的,但某种黑客攻击是可以做到的,我相信这将是这个问题的临时解决方案。 当tab以编程方式切换或点击tab栏项时,将调用tab栏控制器Delegate do your stuff in the的override below方法

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
}

我只关心选项卡栏控制器堆栈中一个VCs中的selectedIndex。因此,我在该VC的tabbarcontroller实例上使用KVO:ed segmentedIndex。工作正常,没有实际问题。

Swift 3

下面是一个更安全的Swift-3版本,上面已经提出:

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])
    }
}
用法:

selectItem(withIndex: 1)

在swift中,您可以通过覆盖
UITabBarController
selectedIndex
属性来执行此操作

第一个子类
UITabBarController
,并添加以下所有代码

//Overriding this to get callback whenever its value is changes
   override var selectedIndex: Int {
      didSet {
         handleTabSelection(selectedIndex: selectedIndex)
      }
   }
还添加了
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)
}
最后,我们从两个地方调用此方法,以便处理所有案例

private func handleTabSelection(selectedIndex: Int) {
    //Do something on tab selection at selectedIndex
}

根据这里的所有答案,如果您已经子类化了
UITabBarController
,那么这里有一个用于所有选项卡栏更改(用户启动和编程)的简单解决方案:


Swift 4:-您必须使用这些代码行来检测
UITabBar
所选项目索引

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

我不确定直接调用委托方法是否是一种好的做法,因为它的目的是自动触发。非常好。。。。为梅曼工作!你救了我的饭碗!非常感谢你!它解决了我在每个选项卡上显示初始vc的最大问题:)
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)
}
private func handleTabSelection(selectedIndex: Int) {
    //Do something on tab selection at selectedIndex
}
// 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) {}
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
    }
}