检测何时按下标签栏项目

时间:2022-08-23 22:36:50

I have a root view controller which isn’t set as the custom class for any of my view controllers on my storyboard. Instead, all of my view controllers are subclassing this class like so.

我有一个根视图控制器,它没有设置为我的故事板上任何视图控制器的自定义类。相反,我的所有视图控制器都像这样继承这个类。

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

}

But I seem to be struggling with doing something when a tabbaritem is pressed on the view controller which is subclassing the rootviewcontroller, i.e, the message is not being printed.

但是,当在视图控制器上按下tabbaritem时,我似乎正在努力做某事,该视图控制器是rootviewcontroller的子类,即消息未被打印。

3 个解决方案

#1


46  

You don't want your view controller's base class to be a UITabBarDelegate. If you were to do that, all of your view controller subclasses would be tab bar delegates. What I think you want to do is to extend UITabBarController, something like this:

您不希望视图控制器的基类是UITabBarDelegate。如果您这样做,所有视图控制器子类都将是标签栏代理。我认为你想要做的是扩展UITabBarController,如下所示:

class MyTabBarController: UITabBarController, UITabBarControllerDelegate {

then, in that class, override viewDidLoad and in there set the delegate property to self:

然后,在该类中,覆盖viewDidLoad并在其中将delegate属性设置为self:

self.delegate = self

Note: This is setting the tab bar controller delegate. The tab bar has it's own delegate (UITabBarDelegate), which the tab bar controller manages, and you are not allow to change.

注意:这是设置标签栏控制器委托。标签栏有自己的委托(UITabBarDelegate),标签栏控制器管理,您不允许更改。

So, now this class is both a UITabBarDelegate (because UITabBarController implements that protocol), and UITabBarControllerDelegate, and you can override/implement those delegate's methods as desired, such as:

所以,现在这个类都是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")
}

I'm guessing you're probably more interested in the latter. Check out the documentation to see what each of these delegates provide.

我猜你可能对后者更感兴趣。查看文档以了解每个代表提供的内容。

Last thing, in your storyboard (assuming you are using storyboards), set your tab bar controller's class to MyTabBarController in the Identity Inspector, and you're good to go.

最后,在你的故事板中(假设你正在使用故事板),在Identity Inspector中将标签栏控制器的类设置为MyTabBarController,你就可以了。

Swift 3/4

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

#2


25  

Doing it this way caused me an error

这样做会导致我出错

Changing the delegate of a tab bar managed by a tab bar controller is not allowed

不允许更改由选项卡栏控制器管理的选项卡栏的委托

This is what I did and it worked

这就是我所做的,它的工作原理

  1. In you ViewController you inherit UITabBarControllerDelegate
  2. 在ViewController中,您继承了UITabBarControllerDelegate
  3. Set delegate in a viewDidLoad
  4. 在viewDidLoad中设置委托
  5. Add a function
  6. 添加一个功能

Example:

例:

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
   }

}

#3


1  

Here is a version of @mbeaty's answer with a little more context. It is adapted from my fuller answer here.

这是@ mbeaty的一个版本,带有更多的上下文。它改编自我在这里的更全面的答案。

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

Set this as the Custom class of your Tab View Controller in IB.

将其设置为IB中选项卡视图控制器的自定义类。

检测何时按下标签栏项目

Alternate solution

替代解决方案

  • Just do something in the viewDidLoad method of the tab's view controller. See this answer.
  • 只需在选项卡视图控制器的viewDidLoad方法中执行某些操作即可。看到这个答案。

#1


46  

You don't want your view controller's base class to be a UITabBarDelegate. If you were to do that, all of your view controller subclasses would be tab bar delegates. What I think you want to do is to extend UITabBarController, something like this:

您不希望视图控制器的基类是UITabBarDelegate。如果您这样做,所有视图控制器子类都将是标签栏代理。我认为你想要做的是扩展UITabBarController,如下所示:

class MyTabBarController: UITabBarController, UITabBarControllerDelegate {

then, in that class, override viewDidLoad and in there set the delegate property to self:

然后,在该类中,覆盖viewDidLoad并在其中将delegate属性设置为self:

self.delegate = self

Note: This is setting the tab bar controller delegate. The tab bar has it's own delegate (UITabBarDelegate), which the tab bar controller manages, and you are not allow to change.

注意:这是设置标签栏控制器委托。标签栏有自己的委托(UITabBarDelegate),标签栏控制器管理,您不允许更改。

So, now this class is both a UITabBarDelegate (because UITabBarController implements that protocol), and UITabBarControllerDelegate, and you can override/implement those delegate's methods as desired, such as:

所以,现在这个类都是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")
}

I'm guessing you're probably more interested in the latter. Check out the documentation to see what each of these delegates provide.

我猜你可能对后者更感兴趣。查看文档以了解每个代表提供的内容。

Last thing, in your storyboard (assuming you are using storyboards), set your tab bar controller's class to MyTabBarController in the Identity Inspector, and you're good to go.

最后,在你的故事板中(假设你正在使用故事板),在Identity Inspector中将标签栏控制器的类设置为MyTabBarController,你就可以了。

Swift 3/4

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

#2


25  

Doing it this way caused me an error

这样做会导致我出错

Changing the delegate of a tab bar managed by a tab bar controller is not allowed

不允许更改由选项卡栏控制器管理的选项卡栏的委托

This is what I did and it worked

这就是我所做的,它的工作原理

  1. In you ViewController you inherit UITabBarControllerDelegate
  2. 在ViewController中,您继承了UITabBarControllerDelegate
  3. Set delegate in a viewDidLoad
  4. 在viewDidLoad中设置委托
  5. Add a function
  6. 添加一个功能

Example:

例:

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
   }

}

#3


1  

Here is a version of @mbeaty's answer with a little more context. It is adapted from my fuller answer here.

这是@ mbeaty的一个版本,带有更多的上下文。它改编自我在这里的更全面的答案。

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

Set this as the Custom class of your Tab View Controller in IB.

将其设置为IB中选项卡视图控制器的自定义类。

检测何时按下标签栏项目

Alternate solution

替代解决方案

  • Just do something in the viewDidLoad method of the tab's view controller. See this answer.
  • 只需在选项卡视图控制器的viewDidLoad方法中执行某些操作即可。看到这个答案。