我正在尝试实现类似于 Tweetie 应用程序的UI,其行为如下:顶级视图控制器似乎是导航控制器,其根视图是“帐户” “表视图。如果您点击任何帐户,它将转到第二级,其底部有一个标签栏。每个选项卡项都显示不同的列表,并允许您进一步向下钻取(后续级别不显示选项卡栏)。
因此,这似乎是实现层次结构:
UINavigationController
UITableViewController
UITabBarController
UITableViewController
UITableViewController
这似乎有效[^ 1],但根据-pushViewController:animated:
的SDK文档(强调添加)似乎不受支持:
viewController :被推入堆栈的视图控制器。 它不能是标签栏控制器的实例。
我想避免使用私有API等,但我不确定为什么这种用法被明确禁止,即使它似乎工作正常。有人知道原因吗?
我考虑过将标签栏控制器作为主控制器,每个标签都包含单独的导航控制器。这个问题是每个导航控制器需要共享一个根视图控制器(即 Tweetie 中的“帐户”表) - 这似乎不起作用:将表控制器推送到第二个导航控制器似乎从第一个删除它。更不用说选择不同帐户时的所有簿记可能会很痛苦。
我该如何以正确的方式实现这一目标?
[^ 1]:标签栏控制器需要进行子类化,以便该级别的标签栏控制器导航项与所选标签的导航项保持同步,并且单个标签的表控制器需要推送各自的详细视图到self.tabBarController.navigationController
而不是self.navigationController
。
答案 0 :(得分:63)
之前的两个答案是对的 - 我没有在Tweetie中使用UITabBarController
。编写一个自定义XXTabBarController
(UIViewController
的简单子类)很容易被推到导航控制器堆栈上,但仍然遵循“视图控制器”的理念。帐户特定视图(Tweets
/ Replies
/ Messages
)上的每个“标签”都是自己的视图控制器,就他们而言,他们会在屏幕上交换通过简单的UITabBarController
。
答案 1 :(得分:34)
我正在构建一个使用与Tweetie类似的导航框架的应用程序。我在我的博客www.wiredbob.com上写了一篇关于如何执行此操作的帖子,该帖子也链接到源代码。这是一个完整的模板,您可以将其作为另一个项目的基础。祝你好运!
答案 2 :(得分:10)
可以将UITabBar添加到任何UIViewController。这样你实际上不必推送UITabBarController,因此保持在Apple API的指导范围内。
在界面构建器中,UITabBar位于Cocoa Touch库中的“Windows,Views& Bars”下。
答案 3 :(得分:9)
我在几个应用程序中执行此操作。将标签栏添加到基于navigationController的应用程序的技巧是不使用TabBarController。向视图添加选项卡栏,使该视图的视图控制器成为TabBarDelegate,并在视图控制器的代码中的选项卡栏上响应用户选择。
我使用Tab Bars将其他视图作为子视图添加到Tab Bar的视图,使用不同的数据集重新加载表视图,重新加载UIPickerView等。
答案 4 :(得分:6)
我在过去一小时内一直在努力实施UITabBar
,因为当我试图展示我的观点时它会被隐藏起来;然后我找到了post:
基本上,请确保按照以下代码行在标签栏下方插入新视图:
[self.view insertSubview:tab2ViewController.view belowSubview:myTabBar];
答案 5 :(得分:3)
在我的应用程序中,根视图控制器是一个UINavigation控制器。在应用程序的某个点上,我需要显示一个UITabBar。我尝试在导航层次结构中的UIView上实现UITabBar,正如之前的一些帖子所建议的那样,这确实有效。但我发现我想要更多的标签控制器提供的默认行为,我找到了一种方法来使用UITabBarController和UINavigation控制器:
1)当我想显示UITabBarController的视图时,我这样做:
MyAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
appDelegate.window.rootViewController = myUiTabBarControllerInstance;
2)当我想回到我在导航层次结构中的位置时,我这样做:
appDelegate.window.rootViewController = myNavControllerInstance;
答案 6 :(得分: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];
}
答案 7 :(得分:2)
这可以通过简单地在导航控制器中嵌入TabBarController来实现。 在故事板中:
在这种情况下,只有TabBarController的RootViewController将位于导航控制器的堆栈中。所有TabBarItems都会在顶部显示导航栏,用户可以随时进入主屏幕,无论选择的TabBarItem如何
这可以在导航控制器堆栈中的任何ViewController上完成。
如果有效,请建议我如何提高声誉,以便我可以在下一个答案中发布图像和代码。 :)
答案 8 :(得分:1)
我写了一篇关于我如何解决这个问题的博客文章。对我来说,使用模态视图比编写自定义标签栏实现更简单。
http://www.alexmedearis.com/uitabbarcontroller-inside-a-uinavigationcontroller/