#iphone #uinavigationcontroller #uitabbarcontroller
#iPhone #uinavigationcontroller #uitabbarcontroller
Вопрос:
moreViewController, который появляется на панели вкладок с более чем 5 элементами, похоже, правильно обрабатывает контроллеры просмотра, но не контроллеры навигации. Кто-нибудь может объяснить, почему это так?
Вот как воспроизвести проблему в прозе, а затем в коде:
Я создаю простое приложение с 6 UIViewControllers на 6 вкладках. Поскольку у меня более 5 вкладок, вкладки «5» и «6» находятся в moreNavigationList. 6-я вкладка содержит кнопку, которая при нажатии удаляет первую вкладку. Это уменьшает количество вкладок до 5, поэтому moreNavigationController больше не требуется и исчезает. Вкладка «6» теперь перемещается в последнее место панели вкладок. Все, как ожидалось.
Теперь, если поместить контроллер просмотра с вкладки «6» (то есть тот, у которого есть кнопка) в навигационный контроллер, все сломается. Если я нажму кнопку, вкладка «1» будет удалена с панели вкладок, moreNavigationController исчезнет, а вкладка «6» теперь отображается в последнем месте панели вкладок. Однако его содержимое исчезло. Нет кнопки, ничего нет.
Анализируя иерархию представлений, похоже, происходит то, что moreNavigationController удаляет контроллер представления «6» из своего исходного контроллера навигации в [TabBarController ViewControllers] и добавляет его в свой собственный стек. Но, похоже, это не возвращает его обратно, когда 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
Комментарии:
1. вы нашли решение этой проблемы? Я застрял в том, чтобы заставить moreNavigationController вывести pushed controller, чтобы этот контроллер вернулся в исходный навигационный стек… Я обнаружил, что у частного
UIMoreNavigationController
класса UIKit есть частный-_restoreOriginalNavigationController
метод, но это просто говорит о том, что moreNavigationController портит навигационные стеки.
Ответ №1:
Я столкнулся с той же проблемой и потратил часы на поиск решений. Как оказалось, на самом деле такого нет.
Проблема заключается во вложенных навигационных контроллерах. Ваш навигационный контроллер помещается в moreNavigationController, и ошибка возникает при его извлечении. Как подсказывает delirus, вы можете использовать [moreNavigationController popToRootViewControllerAnimated:]
, чтобы получить вложенные представления навигационного контроллера и поместить их в новый навигационный контроллер и отобразить это. Я попробовал это и обнаружил, почему эта проблема так и не была исправлена: ваши панели навигации будут «перекрываться».
Если вы углубитесь на несколько просмотров в навигационный контроллер, а затем он будет помещен в moreNavigationController, кнопка возврата moreNavigationController заменит кнопку возврата вашего навигационного контроллера. Есть несколько других ситуаций, с которыми вы столкнетесь, когда панели навигации будут конфликтовать.
Вы могли бы создать вторую панель инструментов со своими собственными кнопками возврата или переопределить принцип работы кнопки «Еще», но я обнаружил, что для обеспечения интуитивности пользователя есть только два обходных пути — не встраивать контроллеры навигации в контроллеры панели вкладок или ограничить количество вкладок.
Я понимаю, что этот вопрос старый, но я надеюсь, что этот ответ избавит кого-то от некоторых проблем. Если у кого-нибудь есть какие-либо вопросы (или предложения по другим обходным путям!) дайте мне знать.