web-dev-qa-db-ja.com

プログラムで設定されたUITabBarの選択されたインデックス/アイテムの変更を検出する

選択したTabBarアイテムまたはインデックスが変更されたときにどのように検出するか知りたいwhen変更はプログラムで行われます

self.tabBarController.selectedIndex = 1;

この2つのデリゲート関数は、tabBarアイテムがユーザーによって選択された場合にのみ変更を検出します。 selectedIndexへの変更がプログラムで行われた場合は発生しません。

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

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

変更を「検出」するには以前の回答で十分ですが、どのインデックスが押されているかは検出されません。

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
    }
}
18
Eddy Liu

ここですべての回答に沿って、すでに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) {}
15
Meseery

Swiftでは、selectedIndexUITabBarControllerプロパティをオーバーライドすることでそれを行うことができます。

最初に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
}
2
Vineet Ashtekar

それはできませんが、ある種のハッキングを行うことができ、この問題の一時的な解決策になると確信しています。 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
}
1
Amit Saxena

Swift

これは、上記で提案されているものの、いくぶん安全な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)
1
jeff-ziligy

これに対する素敵な解決策を見つけました。アイデアを提供してくれたCkoutaに感謝します。

単にインデックスを変更する関数を作成し、UITabBarのdidSelectItemのデリゲートプロトコルを起動します

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

使用法

    selectItemWithIndex(1);
0
JayVDiyk

Swift 4:- UITabBarで選択された項目のインデックスを検出するには、このコード行を使用する必要があります。

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

    if item == (tabBar.items)![0] {

    }
    else if item == (tabBar.items)![1] {

    }
}
0
V.Kumar

タブバーコントローラースタックのVCの1つでselectedIndexのみを気にしました。だから私はそのVCからtabbarcontrollerインスタンスのsegmentedIndexをKVO:しました。問題なく動作します。

0
Jonny