web-dev-qa-db-ja.com

タブバー項目が押されたことを検出する

ストーリーボード上のどのビューコントローラーのカスタムクラスとしても設定されていないルートビューコントローラーがあります。代わりに、すべてのView Controllerはこのようにこのクラスをサブクラス化しています。

// RootViewController
class RootViewController: UIViewController, UITabBarDelegate { 

    // This is not getting executed on any of the view controllers
    func tabBar(tabBar: UITabBar, didSelectItem item: UITabBarItem) {
        print("ddd")
    }
}

// Subclassing it 
class TopStoriesViewController: RootViewController {

}

しかし、rootviewcontrollerをサブクラス化しているView ControllerでTabbarItemが押されたとき、つまり、メッセージが印刷されていないときに、何かをすることに苦労しているようです。

38
Tunds

View Controllerの基本クラスをUITabBarDelegateにすることは望ましくありません。その場合、View ControllerのサブクラスはすべてTab Barデリゲートになります。あなたがやりたいと思うのは、UITabBarControllerを拡張することです。

class MyTabBarController: UITabBarController, UITabBarControllerDelegate {

次に、そのクラスでviewDidLoadをオーバーライドし、デリゲートプロパティをselfに設定します。

self.delegate = self

注:これは、Tab Bar Controllerデリゲートを設定しています。 Tab Barには、Tab Bar Controllerが管理する独自のデリゲート(UITabBarDelegate)があり、変更することはできません。

したがって、このクラスはUITabBarDelegate(UITabBarControllerがそのプロトコルを実装しているため)とUITabBarControllerDelegateの両方であり、次のようにこれらのデリゲートのメソッドをオーバーライド/実装できます。

// UITabBarDelegate
override func tabBar(tabBar: UITabBar, didSelectItem item: UITabBarItem) {
    print("Selected item")
}

// UITabBarControllerDelegate
func tabBarController(tabBarController: UITabBarController, didSelectViewController viewController: UIViewController) {
    print("Selected view controller")
}

おそらく後者に興味があると思います。これらの各デリゲートが提供するものを確認するには、ドキュメントをご覧ください。

最後に、ストーリーボード(ストーリーボードを使用している場合)で、Identity InspectorでTab Bar ControllerのクラスをMyTabBarControllerに設定します。これで準備完了です。

Swift 3/4

// UITabBarDelegate
override func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) {
    print("Selected item")
}

// UITabBarControllerDelegate
func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) {
    print("Selected view controller")
}
71
mbeaty

この方法で実行するとエラーが発生しました

Tab Bar Controllerによって管理されるTab Barのデリゲートを変更することはできません

これは私がやったことですworked

  1. あなたViewControllerであなたはUITabBarControllerDelegateを継承します
  2. viewDidLoadにデリゲートを設定します
  3. 機能を追加する

例:

class MyClass: UIViewController, UITabBarControllerDelegate {

   func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) {
        let tabBarIndex = tabBarController.selectedIndex
        if tabBarIndex == 0 {
            //do your stuff
        }
   }

   override func viewDidLoad() {
        super.viewDidLoad()
        self.tabBarController?.delegate = self
   }

}
43
Gulz

以下に、@ mbeatyの回答のも​​う1つのコンテキストを示します。それは私の ここのより完全な答え から適合されています。

import UIKit

class MyTabBarController: UITabBarController, UITabBarControllerDelegate {

    override func viewDidLoad() {
        super.viewDidLoad()

        // tell our UITabBarController subclass to handle its own delegate methods
        self.delegate = self
    }

    // called whenever a tab button is tapped
    func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) {

        if let firstVC = viewController as? FirstViewController {
            firstVC.doSomeAction()
        }

        if viewController is FirstViewController {
            print("First tab")
        } else if viewController is SecondViewController {
            print("Second tab")
        }
    }

    // alternate method if you need the tab bar item
    override func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) {
        // ...
    }
}

これをIBのTab View Controllerのカスタムクラスとして設定します。

enter image description here

代替ソリューション

  • タブのView ControllerのviewDidLoadメソッドで何かをするだけです。 この回答 を参照してください。
6
Suragch

同じView Controllerが選択されていることを知る必要があるため、このコードを使用しました。

import UIKit

protocol CustomTabBarControllerDelegate {
    func onTabSelected(isTheSame: Bool)
}

class CustomTabBarController: UITabBarController, UITabBarControllerDelegate {
    override func viewDidLoad() {
        super.viewDidLoad()
        self.delegate = self
    }

    func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool {
        (viewController as? CustomTabBarControllerDelegate)?.onTabSelected(isTheSame: selectedViewController == viewController)
        return true
    }
}

最初のタブビューコントロール

import UIKit

class Tab1ViewController: UIViewController, CustomTabBarControllerDelegate {
    func onTabSelected(isTheSame: Bool) { 
        print("Tab1ViewController onTabSelected")
        //do something
    }
}

2番目のタブビューコントロール

import UIKit

class Tab2ViewController: UIViewController, CustomTabBarControllerDelegate {
    func onTabSelected(isTheSame: Bool) { 
        print("Tab2ViewController onTabSelected")
        //do something
    }
}

CustomTabBarControllerをストーリーボードのTabBarControllerのカスタムクラスとして設定し、すべてのTab View ControllerによってCustomTabBarControllerDelegateプロトコルを実装することを忘れないでください。

UINavigationControllerを使用する場合、UINavigationControllerがストーリーボードエントリポイントでないと機能しません。以下のようなストーリーボード構造があることを確認してください。

The structure of storyboard

1
Zhebzhik Babich