#objective-c #uitabbarcontroller #ios5
#objective-c #uitabbarcontroller #ios5
Вопрос:
У меня есть следующий код для UITabBarController:
NSMutableArray *arr = [[NSMutableArray alloc] init];
tabBarController = [[UITabBarController alloc] init];
FirstViewController *firstview = [[FirstViewController alloc] init];
[tabBarControllerViews addObject:firstview];
[firstview release];
SecondViewController *secondview = [[SecondViewController alloc] init];
[tabBarControllerViews addObject:secondview];
[secondview release];
[tabBarController setViewControllers:arr animated:YES];
[arr release];
self.view = tabBarController.view;
Этот код отлично работает на IOS4. Я попробовал это на бета-версии IOS5 и получаю следующую ошибку при нажатии на элемент UITabBarItem:
*** Terminating app due to uncaught exception 'UIViewControllerHierarchyInconsistency',
reason: 'child view controller:<FirstViewController: 0x6e03be0> should have parent view
controller:<MainViewController: 0x6816d20> but actual parent is:<UITabBarController: 0x6b0c110>'
Ответ №1:
заменить:
self.view = tabBarController.view;
с:
[self.view addSubview:tabBarController.view];
Это также будет обратно совместимо с IOS3 и 4.
Ответ №2:
В моем коде был тот же шаблон (и проблема). Решение Джо у меня не сработало. Глядя на фрагмент, я предполагаю, что вы производите класс от UIViewController, чтобы позволить вам что-то настраивать.
Что нужно сделать здесь, и это довольно просто, это вывести из UITabBarController, а не UIViewController, не создавайте TabBarController, и везде, где вы ссылаетесь на TabBarController, замените self .
5 минут, и вы больше не создаете исключение несоответствия и остаетесь обратно совместимыми с iOS 4. Вы все еще можете выполнить все свои настройки в своем производном классе (манипулировать навигационным контроллером и т.д.).
Если вы создали сложную производную от UIViewController, которую вам нужно использовать, это может потребовать больше работы.
Одна небольшая ошибка — если вы переопределите loadView, вы обнаружите, что он вызывается во время инициализации для UITabBarController. Затрудняет установку элементов до loadView, поэтому вам может потребоваться разделить вашу инициализацию.
Удачи!
Комментарии:
1. Проблема с заменой self.view = TabBarController.view; на self.view addSubview: TabBarController.view, как предложено ниже, заключается в том, что у вас все та же несогласованность в иерархии контроллеров представления, вы взяли представление с одного контроллера представления и вставили его в другой контроллер представления. Если Apple ужесточит проверку для этих случаев, этот код в какой-то момент в будущем завершится ошибкой. Посмотрите видео сеанса 102 с WWDC 2011 на iTunes U для получения дополнительной информации.
2. Полностью согласен с Мэттом. Создание подкласса из UITabBarController вместо UIViewController помогло решить проблему, а также сохранить обратную совместимость.
3. @настройки интерфейса ViewController: UITabBarController <UITabBarControllerDelegate>
4. Я нахожусь в процессе решения этой же проблемы… Я не закончил, но похоже, что это, вероятно, правильный способ думать об этом. Однако я понимаю, почему я в замешательстве… В документах для UITabBarController сказано — прямо в быстрой справке: » Этот класс не предназначен для создания подклассов. Вместо этого вы используете его экземпляры как есть, чтобы представить интерфейс, который позволяет пользователю выбирать между различными режимами работы.» Устарели ли документы? Я пытаюсь обновить приложение, которое я написал и не трогал в течение года, и я предполагаю, что именно поэтому я не стал его подклассом в первую очередь.
5. да, на самом деле, у меня это не сработало. Возможно, я делаю это неправильно, и когда я копну глубже, я узнаю, что это действительно был правильный путь — но в документах говорится, что этого не следует делать, а другой способ сработал без каких-либо изменений в моем собственном коде.
Ответ №3:
Вы не можете отправить или представить UITabBarViewController. Является ли ваш первый контроллер просмотра UITabBarController?
Ответ №4:
Я боролся с той же проблемой.
При создании нового приложения с основными деталями (без раскадровки) вы можете увидеть эти коды ниже из AppDelegate.m.
MasterViewController *masterViewController = [[MasterViewController alloc] initWithNibName:@"MasterViewController" bundle:nil];
self.navigationController = [[UINavigationController alloc] initWithRootViewController:masterViewController];
self.window.rootViewController = self.navigationController;
[self.window makeKeyAndVisible];
«НЕ ЗАВИСЕТЬ ОТ MainWindow»
Просто запустите свой собственный ViewController и установите для него значение делегировать.
И не забудьте отсоединить view от MainWindow.xib, иначе view будет вызван 2 раза.