简体   繁体   English

以编程方式切换到TabBar选项卡视图?

[英]Switching to a TabBar tab view programmatically?

Let's say I have a UIButton in one tab view in my iPhone app, and I want to have it open a different tab in the tab bar of the TabBarController . 假设我的iPhone应用程序中的一个标签视图中有一个UIButton ,我想让它在TabBarController的标签栏中打开一个不同的标签。 How would I write the code to do this? 我该如何编写代码来执行此操作?

I'm assuming I unload the existing view and load a specific tab view, but I'm not sure how to write the code exactly. 我假设我卸载现有视图并加载特定的选项卡视图,但我不确定如何准确编写代码。

Try this code in Swift or Objective-C 在Swift或Objective-C中尝试此代码

Swift 迅速

self.tabBarController.selectedIndex = 1

Objective-C Objective-C的

[self.tabBarController setSelectedIndex:1];

Note that the tabs are indexed starting from 0. So the following code snippet works 请注意,选项卡从0开始编制索引。因此,以下代码段有效

tabBarController = [[UITabBarController alloc] init];
.
.
.
tabBarController.selectedViewController = [tabBarController.viewControllers objectAtIndex:4];

goes to the fifth tab in the bar. 转到栏中的第五个标签。

My opinion is that selectedIndex or using objectAtIndex is not necessarily the best way to switch the tab. 我的观点是selectedIndex或使用objectAtIndex不一定是切换选项卡的最佳方式。 If you reorder your tabs, a hard coded index selection might mess with your former app behavior. 如果您重新排序选项卡,硬编码索引选择可能会破坏您之前的应用程序行为。

If you have the object reference of the view controller you want to switch to, you can do: 如果您有要切换到的视图控制器的对象引用,则可以执行以下操作:

tabBarController.selectedViewController = myViewController

Of course you must make sure, that myViewController really is in the list of tabBarController.viewControllers . 当然,你必须确保,即myViewController真的是在列表中tabBarController.viewControllers

您只需将UITabBarController上的selectedIndex属性设置为适当的索引,就可以像用户点击选项卡按钮一样更改视图。

I tried what Disco S2 suggested, it was close but this is what ended up working for me. 我尝试过迪斯科S2的建议,它很接近,但这最终为我工作。 This was called after completing an action inside another tab. 在另一个选项卡中完成操作后调用此方法。

for (UINavigationController *controller in self.tabBarController.viewControllers)
{
    if ([controller isKindOfClass:[MyViewController class]])
    {
        [self.tabBarController setSelectedViewController:controller];
        break;
    }
}

For cases where you may be moving the tabs, here is some code. 对于您可能正在移动选项卡的情况,这里有一些代码。

for ( UINavigationController *controller in self.tabBarController.viewControllers ) {
            if ( [[controller.childViewControllers objectAtIndex:0] isKindOfClass:[MyViewController class]]) {
                [self.tabBarController setSelectedViewController:controller];
                break;
            }
        }

I wanted to be able to specify which tab was shown by class rather than index as I thought it made for a robust solution that was less dependant on how you wire up IB. 我希望能够指定哪个选项卡是按类而不是索引显示的,因为我认为这是一个强大的解决方案,而不是依赖于如何连接IB。 I didn't find either Disco's or Joped's solutions to work so i created this method: 我没有找到Disco或Joped的解决方案,所以我创建了这个方法:

-(void)setTab:(Class)class{
    int i = 0;
    for (UINavigationController *controller in self.tabBarContontroller.viewControllers){
        if ([controller isKindOfClass:class]){
            break;
        }
        i++;
    }
    self.tabBarContontroller.selectedIndex = i;
}

you call it like this: 你这样称呼它:

[self setTab:[YourClass class]];

Hope this is helpful to someone 希望这对某人有帮助

Like Stuart Clark's solution but for Swift 3: 像Stuart Clark的解决方案,但对于Swift 3:

func setTab<T>(_ myClass: T.Type) {
    var i: Int = 0
    if let controllers = self.tabBarController?.viewControllers {
        for controller in controllers {
            if let nav = controller as? UINavigationController, nav.topViewController is T {
                break
            }
            i = i+1
        }
    }
    self.tabBarController?.selectedIndex = i
}

Use it like this: 像这样使用它:

setTab(MyViewController.self)

Please note that my tabController links to viewControllers behind navigationControllers. 请注意我的tabController链接到navigationControllers后面的viewControllers。 Without navigationControllers it would look like this: 没有navigationControllers,它看起来像这样:

if let controller is T {

My issue is a little different, I need to switch from one childViewController in 1st tabBar to home viewController of 2nd tabBar. 我的问题有点不同,我需要从第一个tabBar中的一个childViewController切换到第二个tabBar的home viewController。 I simply use the solution provided in the upstairs: 我只是使用楼上提供的解决方案:

tabBarController.selectedIndex = 2

However when it switched to the home page of 2nd tabBar, the content is invisible. 但是当它切换到第二个tabBar的主页时,内容是不可见的。 And when I debug, viewDidAppear, viewWillAppear, viewDidLoad, none of them is called. 当我调试viewDidAppear,viewWillAppear,viewDidLoad时,它们都不会被调用。 My solutions is to add the following code in the UITabBarController: 我的解决方案是在UITabBarController中添加以下代码:

override var shouldAutomaticallyForwardAppearanceMethods: Bool 
{
    return true
}

Use in AppDelegate.m file: AppDelegate.m文件中使用:

(void)tabBarController:(UITabBarController *)tabBarController
 didSelectViewController:(UIViewController *)viewController
{

     NSLog(@"Selected index: %d", tabBarController.selectedIndex);

    if (viewController == tabBarController.moreNavigationController)
    {
        tabBarController.moreNavigationController.delegate = self;
    }

    NSUInteger selectedIndex = tabBarController.selectedIndex;

    switch (selectedIndex) {

        case 0:
            NSLog(@"click me %u",self.tabBarController.selectedIndex);
            break;
        case 1:
            NSLog(@"click me again!! %u",self.tabBarController.selectedIndex);
            break;

        default:
            break;

    }

}

Like Stuart Clark's solution but for Swift 3 and using restoration identifier to find correct tab: 像Stuart Clark的解决方案,但对于Swift 3并使用恢复标识符来查找正确的选项卡:

private func setTabById(id: String) {
  var i: Int = 0
  if let controllers = self.tabBarController?.viewControllers {
    for controller in controllers {
      if let nav = controller as? UINavigationController, nav.topViewController?.restorationIdentifier == id {
        break
      }
      i = i+1
    }
  }
  self.tabBarController?.selectedIndex = i
}

Use it like this ("Humans" and "Robots" must also be set in storyboard for specific viewController and it's Restoration ID, or use Storyboard ID and check "use storyboard ID" as restoration ID): 像这样使用它(“人类”和“机器人”也必须在故事板中为特定的viewController和它的恢复ID设置,或者使用故事板ID并检查“使用故事板ID”作为恢复ID):

struct Tabs {
    static let Humans = "Humans"
    static let Robots = "Robots"
}
setTabById(id: Tabs.Robots)

Please note that my tabController links to viewControllers behind navigationControllers. 请注意我的tabController链接到navigationControllers后面的viewControllers。 Without navigationControllers it would look like this: 没有navigationControllers,它看起来像这样:

if controller.restorationIdentifier == id {
import UIKit

class TabbarViewController: UITabBarController,UITabBarControllerDelegate {

//MARK:- View Life Cycle

override func viewDidLoad() {
    super.viewDidLoad()

}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()

}

//Tabbar delegate method
override func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) {
    let yourView = self.viewControllers![self.selectedIndex] as! UINavigationController
    yourView.popToRootViewController(animated:false)
}



}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM