出现在超过5项的选项卡栏中的moreViewController似乎可以正确处理视图控制器,但不能正确处理导航控制器。有人能解释一下为什么会这样吗?
下面是如何用文字再现这个问题,然后用代码再现这个问题:
我创建了一个简单的应用程序,在6个选项卡中有6个uiviewcontroller。由于我有超过5个选项卡,选项卡"5"one_answers"6"驻留在moreNavigationList中。第6个选项卡包含一个按钮,当按下该按钮时,将删除第一个选项卡。这将选项卡的数量减少到5个,因此不再需要moreNavigationController并消失。标签"6"现在移动到标签栏的最后一个位置。一切如我所愿现在,如果把视图控制器从标签"6"(即有按钮的那个)到导航控制器,事情就坏了。如果我按下按钮,选项卡"1"从选项卡栏中删除,moreNavigationController消失,选项卡"6"现在显示在选项卡栏的最后一个位置。然而,它的内容已经消失了。没有按钮,什么都没有。
从分析视图层次结构,似乎正在发生的是moreNavigationController从它原来的导航控制器[tabbarcontrollerviewcontrollers]中删除了"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
我遇到了同样的问题,并花了几个小时寻找解决方案。事实证明,其实并没有。
问题在于嵌套的导航控制器。你的导航控制器被放置在moreNavigationController中,错误发生在它被取出的时候。正如delirus提示的那样,你可以使用[moreNavigationController popToRootViewControllerAnimated:]
来获取导航控制器的子视图,并将它们放在一个新的导航控制器中并显示它。我试了一下,发现了为什么这个问题从来没有解决过:你的导航栏会"重叠"。
如果你在导航控制器中深入几个视图,然后它被放置在moreNavigationController中,moreNavigationController的返回按钮将取代导航控制器的返回按钮。在其他一些情况下,导航条会发生冲突。
你可以创建第二个工具栏,用你自己的后退按钮,或者覆盖更多按钮的工作方式,但我发现,为了保持用户的直觉,只有两个解决方案——不要在标签栏控制器中嵌入导航控制器,或者限制标签的数量。
我知道这个问题很老,但我希望这个答案能为大家省去一些麻烦。如果有人有任何问题(或其他解决方法的建议!)请告诉我。