【问题标题】:Detect UITabBar Selected Index/ Item Changes that is set Programmatically检测以编程方式设置的 UITabBar 选定索引/项目更改
【发布时间】:2015-08-21 22:04:18
【问题描述】:

我想知道我们如何检测选定的 TabBar 项或索引何时更改更改是以编程方式完成的

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

【问题讨论】:

    标签: ios uitabbarcontroller uitabbar uitabbaritem


    【解决方案1】:

    除了这里的所有答案,如果您已经对 UITabBarController 进行了子类化,这里有一个针对所有标签栏更改的简单解决方案(用户启动和程序化):

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

    【讨论】:

    • 男人!你救了我的工作!太感谢了!它解决了我为每个标签显示初始 vc 的最大问题 :)
    【解决方案2】:

    以前的答案足以“检测”更改,但它不检测正在按下哪个索引。

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

    self.selectedIndex 不会立即返回所选索引。要检查哪个项目被按下,我们需要将项目与 UITabBarController

    中的 tabBarItems 进行比较
    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
        }
    }
    

    【讨论】:

    • 我不确定直接调用委托方法是一个好习惯,因为它的目的是自动触发。
    【解决方案3】:

    在swift中,您可以通过覆盖UITabBarControllerselectedIndex属性来实现。

    第一个子类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
    }
    

    【讨论】:

      【解决方案4】:

      斯威夫特 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])
          }
      }
      

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

      用法:

      selectItem(withIndex: 1)
      

      【讨论】:

        【解决方案5】:

        这是无法做到的,但可以通过某种黑客手段来解决,我相信这将是解决此问题的临时解决方案。 覆盖下面的 tabbarcontrollerdelegate 方法,当以编程方式切换选项卡或点击选项卡栏项目时,调用此方法中的内容。

        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】:

          我找到了一个很好的解决方案。感谢 Ckouta 的想法。

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

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

          用法

              selectItemWithIndex(1);
          

          【讨论】:

            【解决方案7】:

            我只关心标签栏控制器堆栈中的一个 VC 中的 selectedIndex。所以我在那个 VC 的 tabbarcontroller 实例上 KVO:ed segmentedIndex。运行良好,没有真正的问题。

            【讨论】:

              【解决方案8】:

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

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2013-01-07
                • 2011-06-23
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2016-12-03
                相关资源
                最近更新 更多