Панели вкладок iPhone moreNavigationController неправильно обрабатывают контроллеры навигации?

#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 заменит кнопку возврата вашего навигационного контроллера. Есть несколько других ситуаций, с которыми вы столкнетесь, когда панели навигации будут конфликтовать.

Вы могли бы создать вторую панель инструментов со своими собственными кнопками возврата или переопределить принцип работы кнопки «Еще», но я обнаружил, что для обеспечения интуитивности пользователя есть только два обходных пути — не встраивать контроллеры навигации в контроллеры панели вкладок или ограничить количество вкладок.

Я понимаю, что этот вопрос старый, но я надеюсь, что этот ответ избавит кого-то от некоторых проблем. Если у кого-нибудь есть какие-либо вопросы (или предложения по другим обходным путям!) дайте мне знать.