80

我正在尝试实现一个类似于Tweetie应用程序中的 UI 结构,其行为如下:顶级视图控制器似乎是一个导航控制器,其根视图是一个“帐户”表视图。如果您单击任何帐户,它将进入第二级,底部有一个标签栏。每个选项卡项显示一个不同的列表,让您可以进一步向下钻取(后续级别不显示选项卡栏)。

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

  • UINavigationController
    1. 账户UITableViewController
    2. UITabBarController
      1. 推文UITableViewController
        • 推文/用户/等的详细视图
      2. 回复UITableViewController
      3. ...

这似乎有效[^1],但根据 SDK 文档似乎不受支持-pushViewController:animated:(强调添加):

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

我想避免使用私有 API 等,但我不确定为什么即使它看起来工作正常,也明确禁止这种用法。有人知道原因吗?

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

我应该如何以正确的方式实施这个?

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

4

9 回答 9

63

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

于 2009-02-23T19:54:49.800 回答
33

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

于 2009-04-29T22:19:25.853 回答
10

可以将 UITabBar 添加到任何 UIViewController。这样,您实际上不必推送 UITabBarController 并因此保持在 Apple API 的指导范围内。

在界面构建器中,UITabBar 位于 Cocoa Touch Library 中的“Windows、Views & Bars”下。

于 2009-02-23T07:59:56.087 回答
10

我在我的几个应用程序中执行此操作。将标签栏添加到基于 navigationController 的应用程序的技巧是不使用 TabBarController。将标签栏添加到视图,使该视图的视图控制器成为 TabBarDelegate,并在视图控制器的代码中响应用户在标签栏上的选择。

我使用选项卡栏将其他视图添加到选项卡栏的视图作为子视图,重新加载具有不同数据集的表格视图,重新加载 UIPickerView 等。

于 2009-02-23T17:00:40.873 回答
6

在过去的一个小时里,我一直在努力实现 aUITabBar因为当我试图显示我的视图时它会被隐藏;然后我发现了这篇文章

基本上,请确保根据这行代码在选项卡栏下方插入新视图:

[self.view insertSubview:tab2ViewController.view belowSubview:myTabBar];
于 2010-01-08T08:31:29.773 回答
3

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

1)当我想显示 UITabBarController 的视图时,我这样做:

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

2)当我想返回到导航层次结构中的位置时,我这样做:

appDelegate.window.rootViewController = myNavControllerInstance;
于 2011-01-17T09:48:54.993 回答
3

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

如果这是真的,苹果是否有可能拒绝将我的应用发布到应用商店?

-(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];
}
于 2011-10-08T08:23:18.157 回答
3

这可以通过简单地将 TabBarController 嵌入到导航控制器中来实现。在故事板中:

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

在这种情况下,只有 TabBarController 的 RootViewController 会在 Navigation Controller 的堆栈中。所有的 TabBarItems 顶部都有导航栏,用户可以随时进入主屏幕,而不管所选的 TabBarItem

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

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

于 2014-11-13T13:03:41.503 回答
1

我写了一篇关于我如何解决这个问题的博客文章。对我来说,使用模态视图比编写自定义标签栏实现更简单。

http://www.alexmedearis.com/uitabbarcontroller-inside-a-uinavigationcontroller/

于 2011-04-12T18:10:43.477 回答