导航控制器内部的标签栏控制器,或共享导航根视图


80

我正在尝试实现一个像Tweetie应用程序中那样结构化的UI ,其行为如下:顶级视图控制器似乎是导航控制器,其根视图是“帐户”表视图。如果单击任何帐户,它将转到第二级,底部具有一个标签栏。每个选项卡项都显示一个不同的列表,并允许您进一步深入(后续级别不显示选项卡栏)。

因此,这似乎是实现层次结构:

  • UINavigationController
    1. 帐户UITableViewController
    2. UITabBarController
      1. 鸣叫UITableViewController
        • 推文/用户/等的详细视图
      2. 回覆UITableViewController
      3. ...

这似乎可行[^ 1],但根据SDK文档-pushViewController:animated:(针对以下内容)似乎不受支持:

viewController:被推入堆栈的视图控制器。它不能是标签栏控制器的实例。

我想避免使用私有API之类的方法,但是我不确定为什么即使在看起来很好的情况下也禁止这种用法。有人知道原因吗?

我考虑过将标签栏控制器作为主控制器,每个标签都包含单独的导航控制器。这样做的问题是每个导航控制器都需要共享一个根视图控制器(即Tweetie中的“ Accounts”表)-这似乎不起作用:将表控制器推到另一个导航控制器似乎将其删除。从第一开始。在选择其他帐户时更不用说所有记账了,可能会很痛苦。

我应该如何正确实施此方法?

[^ 1]:选项卡栏控制器需要子类化,以便该级别的选项卡栏控制器的导航项与所选选项卡的导航项保持同步,并且单个选项卡的表控制器需要将其各自的详细信息视图推送到self.tabBarController.navigationController而不是self.navigationController

Answers:


63

前面的两个答案很正确-我不在UITabBarControllerTweetie中使用。编写自定义XXTabBarController(的普通子类UIViewController)非常容易,它很高兴被推入导航控制器堆栈,但仍然遵循“视图控制器”的理念。特定于帐户的视图(Tweets/ Replies/ Messages)上的每个“标签”都是其自己的视图控制器,就他们而言,它们在屏幕上被普通ol交换了UITabBarController


2
您的自定义选项卡栏控制器类如何处理其子控制器的navigationItem和navigationController属性的管道?
bvanderveen

这在iOS 5中有变化吗?我似乎能够将UITabBarController添加到UINavigationController中而没有太多问题,即使作为根控制器也是如此。
sparkFinder 2012年

33

我正在构建一个使用与Tweetie类似的导航框架的应用程序。我在我的博客www.wiredbob.com上写了一篇有关如何执行此操作的文章,该文章也链接到源代码。这是一个完整的模板,您可以将其用作另一个项目的基础。祝好运!


10
对于那些想知道,该链接所提到的博客文章是wiredbob.com/blog/2009/4/20/...
安·多

@Robert Conn,非常好的教程。我正在使用您的概念,但是由于某种原因,我的tabBar未激活。在实施应用程序时,这是否发生在您身上?
Salcedo

@ASalcedo:我也有这个问题,但是发现这是因为我需要减小与选项卡栏项目关联的视图的大小,默认高度为460,在www.wiredbob.com的源代码中较大。您会看到为标签栏设置的标签项高度设置为369。为了在界面生成器中更改高度,您还必须确保在视图的属性检查器中将状态,顶部和底部栏都设置为none(不立即可见)。
伊扎克,2011年

2
博客文章对我来说已经死了,有人有机会说谎吗?
蒂亚戈·韦洛索


10

可以将UITabBar添加到任何UIViewController中。这样一来,您实际上不必推送UITabBarController,因此不必遵循Apple API的准则。

在界面生成器中,UITAbBar位于Cocoa Touch Library中的“ Windows,视图和栏”下。


1
嗨!@Himadri Choudhury您能否解释“并因此遵守Apple API的准则”-或提供参考?我找不到该指南的内容(我不怀疑它的存在,但我找不到URL)。非常感谢
darksider 2012年

10

我在几个应用程序中都这样做。将选项卡栏添加到基于navigationController的应用程序的技巧是不要使用TabBarController。在视图中添加一个标签栏,使该视图的视图控制器成为TabBarDelegate,并以视图控制器的代码响应用户在标签栏上的选择。

我使用标签栏将其他视图作为子视图添加到标签栏的视图,使用不同的数据集重新加载表视图,重新加载UIPickerView等。


6

在过去的一个小时里,我一直在努力实现a,UITabBar因为当我尝试显示我的视图时它会被隐藏。然后我发现了这个帖子

基本上,请确保按照以下代码行将新视图插入标签栏下方:

[self.view insertSubview:tab2ViewController.view belowSubview:myTabBar];

谢谢,这有助于修复我消失的标签栏。我使用了Robert Conn提出的相同代码,但是当我切换到第二个视图时,ui标签栏消失了。
维杰·卡丹

3

在我的应用程序中,根视图控制器是UINavigation控制器。在应用程序中的某个点,我需要显示一个UITabBar。我尝试过在导航层次结构中的UIView上实现UITabBar,正如之前的一些帖子所建议的那样,这确实可行。但是我发现我想要更多选项卡控制器提供的默认行为,并且找到了一种将UITabBarController与UINavigation控制器一起使用的方法:

1)当我想显示UITabBarController的视图时,执行以下操作:

MyAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
appDelegate.window.rootViewController = myUiTabBarControllerInstance;

2)当我想返回到导航层次结构中的位置时,请执行以下操作:

appDelegate.window.rootViewController = myNavControllerInstance;

3

这可以通过简单地将TabBarController嵌入导航控制器中来实现。在情节提要中:

  1. 拖动一个ViewController
  2. 单击ViewController的场景
  3. 单击编辑器>>嵌入>>导航控制器。
  4. 在同一ViewController上拖动一个按钮。
  5. 拖动一个TabBarController
  6. 通过推Segue Action将ViewController上的按钮连接到TabBarController。

在这种情况下,只有TabBarController的RootViewController会在导航控制器的堆栈中。所有TabBarItems的顶部都将具有导航栏,并且用户可以随时转到主屏幕,而不必考虑所选的TabBarItem

这可以在导航控制器堆栈中的任何ViewController上完成。

如果可行,请建议我如何提高声誉,以便在下一个答案中发布图像和代码。:)


3

这就是我做到的。这实际上是将tabbarcontroller推到导航控制器上。它工作正常。我在文档中找不到苹果不支持这种方式的任何地方。有人可以给我链接到此警告吗?

如果这是事实,那么苹果是否有可能拒绝将我的应用发布到appstore?

-(void)setArrayAndPushNextController
{
    MyFirstViewController *myFirstViewController = [[MyFirstViewController alloc] init];
    MySecondViewController *mySecondViewController = [[MySecondViewController alloc] init];

    myFirstViewController.array = self.array;


    NSArray *array = [[NSArray alloc] initWithObjects:myFirstViewController, mySecondViewController, nil];
    UITabBarController *tab = [[UITabBarController alloc] init];
    tab.viewControllers = array;

    [array release];

    UITabBarItem *item1 = [[UITabBarItem alloc] initWithTitle:@"first title" image:nil tag:1];
    UITabBarItem *item2 = [[UITabBarItem alloc] initWithTitle:@"second title" image:nil tag:2];

    myFirstViewController.tabBarItem = item1;
    mySecondViewController.tabBarItem = item2;

    [self stopAnimatingSpinner];

    [self.navigationController pushViewController:tab animated:YES];

    [tab release];
    [item1 release];
    [item2 release];
}

您可以发布UIViewControllers
Gargo 2012年

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.