iPhone Tab 栏 moreNavigationController 无法正确处理导航控制器?
出现在超过 5 个项目的选项卡栏中的 moreViewController 似乎可以正确处理视图控制器,但不能正确处理导航控制器。谁能解释为什么会这样?
以下是如何在散文中重现问题,然后在代码中重现问题:
我创建了一个简单的应用程序,在 6 个选项卡中包含 6 个 UIViewController。由于我有超过 5 个选项卡,因此选项卡“5”和“6”位于 moreNavigationList 中。 第 6 个选项卡包含一个按钮,按下该按钮即可删除第一个选项卡。这将选项卡的数量减少到 5 个,因此不再需要 moreNavigationController 并消失。选项卡“6”现在移动到选项卡栏的最后一个位置。一切都如预期。
现在,如果将选项卡“6”(即带有按钮的选项卡)中的视图控制器放入导航控制器中,事情就会崩溃。如果我按下按钮,选项卡“1”将从选项卡栏中删除,moreNavigationController 消失,选项卡“6”现在显示在选项卡栏的最后一个位置。然而它的内容已经消失了。没有按钮,什么都没有。
通过分析视图层次结构,似乎发生的情况是 moreNavigationController 从 [tabBarController viewControllers] 中的原始导航控制器中删除了“6”视图控制器,并将其添加到自己的堆栈中。但当 moreNavigationController 消失时,它似乎并没有将其放回去。
这是我用来在一个简单的基于窗口的测试应用程序中重现此代码的代码:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Create a tab bar with 5 regular view controllers and a navigation controller
self.tabBarController = [[[UITabBarController alloc] init] autorelease];
UIViewController* vc1 = [[[UIViewController alloc] init] autorelease]; vc1.title = @"1";
UIViewController* vc2 = [[[UIViewController alloc] init] autorelease]; vc2.title = @"2";
UIViewController* vc3 = [[[UIViewController alloc] init] autorelease]; vc3.title = @"3";
UIViewController* vc4 = [[[UIViewController alloc] init] autorelease]; vc4.title = @"4";
UIViewController* vc5 = [[[UIViewController alloc] init] autorelease]; vc5.title = @"5";
UIViewController* vc6 = [[[UIViewController alloc] init] autorelease]; vc6.title = @"6";
// Add a button that removes tab "1" when pressed to vc6
UIButton *moveButton = [self moveButton];
[vc6.view addSubview:moveButton];
vc6.view.backgroundColor = [UIColor greenColor];
moveButton.center = vc6.view.center;
UINavigationController* navController = [[[UINavigationController alloc] initWithRootViewController:vc6] autorelease];
// Everything is fine if vc6 is added directly instead of inside a navigation controller
NSArray* controllers = [NSArray arrayWithObjects:vc1, vc2, vc3, vc4, vc5, navController, nil];
tabBarController.viewControllers = controllers;
[self.window addSubview:tabBarController.view];
[self.window makeKeyAndVisible];
return YES;
}
- (UIButton *)moveButton
{
UIButton *moveButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
moveButton.frame = CGRectMake(0, 0, 150, 50);
[moveButton setTitle:@"Remove 1" forState:UIControlStateNormal];
[moveButton addTarget:self action:@selector(remove) forControlEvents:UIControlEventTouchUpInside];
return moveButton;
}
- (void)remove
{
// remove 1st tab bar item (this also removes moreNavigationController)
NSMutableArray *viewControllers = [NSMutableArray arrayWithArray:tabBarController.viewControllers];
[viewControllers removeObjectAtIndex:0];
[tabBarController setViewControllers:viewControllers];
}
使用的 SDK 是 4.3
The moreViewController that appears in a tab bar with more than 5 items seems to treat view controllers correctly but not navigation controllers. Can anyone explain why this is the case?
Here's how to reproduce the problem in prose, then in code:
I create a simple app with 6 UIViewControllers in 6 tabs. Since I have more than 5 tabs, tab "5" and "6" reside in the moreNavigationList.
The 6th tab contains a button that, when pressed, removes the first tab. This reduces the number of tabs to 5, so the moreNavigationController is not required anymore and disappears. Tab "6" now moves to the last spot of the tab bar. Everything as expected.
Now, if put the view controller from tab "6" (i.e. the one with the button) into a navigation controller, things break. If I press the button, tab "1" is removed from the tab bar, the moreNavigationController disappears and tab "6" is now displayed in the last spot of the tab bar. However it's content is gone. No button, no nothing.
From analyzing the view hierarchy, what seems to be happening is that the moreNavigationController removes the "6" view controller from its original navigation controller in [tabBarController viewControllers] and adds it to its own stack. But it doesn't seem to put it back when the moreNavigationController disappears.
Here's the code I used to reproduce this in a simple window based test app:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Create a tab bar with 5 regular view controllers and a navigation controller
self.tabBarController = [[[UITabBarController alloc] init] autorelease];
UIViewController* vc1 = [[[UIViewController alloc] init] autorelease]; vc1.title = @"1";
UIViewController* vc2 = [[[UIViewController alloc] init] autorelease]; vc2.title = @"2";
UIViewController* vc3 = [[[UIViewController alloc] init] autorelease]; vc3.title = @"3";
UIViewController* vc4 = [[[UIViewController alloc] init] autorelease]; vc4.title = @"4";
UIViewController* vc5 = [[[UIViewController alloc] init] autorelease]; vc5.title = @"5";
UIViewController* vc6 = [[[UIViewController alloc] init] autorelease]; vc6.title = @"6";
// Add a button that removes tab "1" when pressed to vc6
UIButton *moveButton = [self moveButton];
[vc6.view addSubview:moveButton];
vc6.view.backgroundColor = [UIColor greenColor];
moveButton.center = vc6.view.center;
UINavigationController* navController = [[[UINavigationController alloc] initWithRootViewController:vc6] autorelease];
// Everything is fine if vc6 is added directly instead of inside a navigation controller
NSArray* controllers = [NSArray arrayWithObjects:vc1, vc2, vc3, vc4, vc5, navController, nil];
tabBarController.viewControllers = controllers;
[self.window addSubview:tabBarController.view];
[self.window makeKeyAndVisible];
return YES;
}
- (UIButton *)moveButton
{
UIButton *moveButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
moveButton.frame = CGRectMake(0, 0, 150, 50);
[moveButton setTitle:@"Remove 1" forState:UIControlStateNormal];
[moveButton addTarget:self action:@selector(remove) forControlEvents:UIControlEventTouchUpInside];
return moveButton;
}
- (void)remove
{
// remove 1st tab bar item (this also removes moreNavigationController)
NSMutableArray *viewControllers = [NSMutableArray arrayWithArray:tabBarController.viewControllers];
[viewControllers removeObjectAtIndex:0];
[tabBarController setViewControllers:viewControllers];
}
SDK used is 4.3
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我遇到了同样的问题,花了几个小时寻找解决方案。事实证明,实际上并不存在。
问题是嵌套的导航控制器。您的导航控制器正在放置在 moreNavigationController 中,取出时会出现错误。正如 delirus 提示的那样,您可以使用 [moreNavigationController popToRootViewControllerAnimated:] 获取导航控制器的子视图并将它们放置在新的导航控制器中并显示它。我尝试了这个,发现为什么这个问题从未得到解决:您的导航栏将“重叠”。
如果您深入导航控制器中的几个视图,然后将其放置在 moreNavigationController 中,则 moreNavigationController 的“后退”按钮将取代导航控制器的“后退”按钮。在其他一些情况下,您还会遇到导航栏发生冲突的情况。
您可以使用自己的后退按钮创建第二个工具栏,或者覆盖“更多”按钮的工作方式,但我发现为了保持用户直观,只有两种解决方法 - 不要在选项卡栏控制器中嵌入导航控制器,或者限制选项卡的数量。
我意识到这个问题很老了,但我希望这个答案可以为某人省去一些麻烦。如果有人有任何问题(或对其他解决方法的建议!),请告诉我。
I ran into the same problem, and spent hours looking into solutions. As it turns out, there isn't really one.
The issue is nested Navigation Controllers. Your Navigation Controller is being placed in moreNavigationController, and the error occurs when it's taken out. As delirus hints, you can use
[moreNavigationController popToRootViewControllerAnimated:]
to get the subviews of the Navigation Controller and place them in a new Navigation Controller and display that. I tried this, and found why this issue has never been fixed: Your Navigation Bars will "overlap".If you go a few views deep in a Navigation Controller, and then it is placed in moreNavigationController, moreNavigationController's Back button will replace your Navigation Controller's Back button. There are a few other situations you'll run into where the Navigation Bars will conflict.
You could create a second toolbar, with your own back buttons, or override how the More button works, but I've found that to remain user intuitive there are only two workarounds - don't embed Navigation Controllers in Tab Bar Controllers, or limit the number of tabs.
I realize this question is a old, but I hope this answer saves someone some trouble. If anyone has any questions (or suggestions for other workarounds!) let me know.