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


159

假设我UIButton在iPhone应用程序中有一个标签视图,而我想让它在的标签栏中打开其他标签TabBarController。我将如何编写代码来做到这一点?

我假设我要卸载现有视图并加载特定的选项卡视图,但是我不确定如何准确地编写代码。


我有上述方法,家伙在我的[问题]求助[1] [1]的问题:stackoverflow.com/questions/19742416/...
罗马Simenok

Answers:


399

在Swift或Objective-C中尝试此代码

迅速

self.tabBarController.selectedIndex = 1

目标C

[self.tabBarController setSelectedIndex:1];

8
请注意,如果索引映射到“更多”视图控制器中的一个选项卡(应该有五个以上的选项卡),则此方法将不起作用。在这种情况下,请使用-setSelectedViewController:
Joe D'Andrea

完成此操作并成功更改选项卡后,我将无法再正常选择选项卡栏。更新:这与我在以编程方式交换选项卡之前立即调用popToRootViewController有关。
亚当·约翰斯

但是,如果我想切换标签页,Self不会起作用。假设我单击选项卡3并在用户按ok时立即显示alertView,我想再次切换到选项卡1。自我不会是正确的,因为它不是当前的对象。对吗
Alix

这很好用,但是我还必须在切换选项卡时传递数据。我在标签中有一个标签,在我切换到该标签后,需要在切换标签后立即对其进行更新。有什么简单的解决方案吗?
莱兹

@AdamJohns您如何设法解决问题。使它的行为类似于本机的tabBar。第二次单击时,它将弹出到rootViewController。
Waqas

20

请注意,这些标签的索引从0开始。因此,以下代码段有效

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

转到栏中的第五个标签。


12

我的意见是selectedIndex或使用objectAtIndex不一定是切换选项卡的最佳方法。如果您对标签进行重新排序,则硬编码的索引选择可能会与您以前的应用行为混淆。

如果您具有要切换到的视图控制器的对象引用,则可以执行以下操作:

tabBarController.selectedViewController = myViewController

当然,您必须确保myViewController确实在的列表中tabBarController.viewControllers


据我所知,我需要选择更多的NavController,这是唯一的方法
Ossir

9

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


6
一个小的区别是未调用可以通知用户切换选项卡的委托方法。
Brad The App Guy

3
selectedIndex索引> 4的设置对我也不起作用,但是selectedViewController可以。
bugloaf 2012年

3

我尝试了Disco S2的建议,结果很接近,但这最终对我有用。在另一个选项卡中完成一个动作后调用此方法。

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

2

对于可能移动选项卡的情况,下面是一些代码。

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

2

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

像这样使用它:

setTab(MyViewController.self)

请注意,我的tabController链接到navigationControllers后面的viewControllers。如果没有navigationControllers,它将看起来像这样:

if let controller is T {

没有循环,就没有导航控制器:func selectViewController <ViewControllerModel>(type:ViewControllerModel.Type){self.selectedViewController = self.viewControllers?.first(其中:{viewController中的viewController是ViewControllerModel})}
dev_exo

1

我希望能够指定按类别而不是按索引显示哪个选项卡,因为我认为它是一种健壮的解决方案,该解决方案较少依赖于IB的连接方式。我没有找到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;
}

您这样称呼它:

[self setTab:[YourClass class]];

希望这对某人有帮助


这很棒!我在另一个答案中为Swift3重写了它。
杰森

1

我的问题有点不同,我需要从第一个tabBar中的一个childViewController切换到第二个tabBar的主viewController。我只是使用楼上提供的解决方案:

tabBarController.selectedIndex = 2

但是,当切换到第二个tabBar的主页时,该内容是不可见的。当我调试viewDidAppear,viewWillAppear,viewDidLoad时,没有一个被调用。我的解决方案是在UITabBarController中添加以下代码:

override var shouldAutomaticallyForwardAppearanceMethods: Bool 
{
    return true
}

0

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;

    }

}

0

类似于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
}

像这样使用它(还必须在情节提要中为特定的viewController设置“人类”和“机器人”及其还原ID,或使用情节提要ID并选中“使用情节提要ID”作为还原ID):

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

请注意,我的tabController链接到navigationControllers后面的viewControllers。如果没有navigationControllers,它将看起来像这样:

if controller.restorationIdentifier == id {

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



}

1
通常,最好解释一个解决方案,而不是仅仅发布一些匿名代码行。您可以阅读《我如何写一个好的答案》,也可以解释完全基于代码的答案
Anh Pham,
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.