viewWillAppear, viewDidAppear не вызывается, не запускается
(это и вопрос, и ответ, так как потребовалось довольно много копать, чтобы найти реальный ответ.)
симптомы: viewWillAppear
, viewDidAppear
не вызывались в моем UIViewController.
причина: вложение UINavigationController
или UITabBarController
(мой случай) в UIViewController
как-то прерывается при вызове этих методов.
решение: вызовите их вручную в UIViewController
, который содержит вышеупомянутый UINavigationController
/ UITabBarController
.
например (предполагая projectNavigationController
ваш UINavigationController
):
-(void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; [projectNavigationController viewWillAppear:animated]; } -(void)viewWillDisappear:(BOOL)animated { [super viewWillDisappear:animated]; [projectNavigationController viewWillDisappear:animated]; } -(void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; [projectNavigationController viewDidAppear:animated]; } -(void)viewDidDisappear:(BOOL)animated { [super viewDidDisappear:animated]; [projectNavigationController viewDidDisappear:animated]; }
в моем случае у меня был внутренний UITabBarController
и я назвал методы, соответственно и все решалось.
(атрибуция решения: http://davidebenini.it/2009/01/03/viewwillappear-not-being-called-inside-a-uinavigationcontroller/)
2 ответов
я собираюсь пойти вперед и не согласиться с @St3fan и использовать UIKit
как контр-пример.
однако мудрость (или ее отсутствие) встраивания контроллеров в целом должна руководствоваться здравыми принципами проектирования пользовательского интерфейса.
самый простой контр-пример UINavigationControllers
встроенные в UITabBarControllers
. Они появляются повсюду. Просто с моей головы, приложение iPod на iPhone и контакты в приложении телефона на айфон.
мне было достаточно любопытно, чтобы проверить, что они делают с представлениями (добавьте в представление "супер-контроллер" или в UIWindow
. Я был уверен, что найду, что представления субконтроллера являются потомками представлений суперконтроллера в иерархии представлений, что противоречит рекомендации St3fan.
я взбитые очень быстрый iPhone приложение подключения все в InterfaceBuilder, чтобы создать UITabBarController
приложение с двумя вкладками, первая из которых был UINavigationController
С простой ole UIViewController
как это контроллер корневого представления и 2-я вкладка с простым старым UIViewController
просто так у меня была вкладка 2nd, чтобы нажать позже.
посыпать в некоторых NSLog
заявления для вывода различных UIView's
для контроллеров мы видим это:
tabBarController.view = <UILayoutContainerView: 0x5b0dc80; ...
navigationController.view = <UILayoutContainerView: 0x59469a0; ...
rootViewController.view = <UIView: 0x594bb70; ...
Superview: <UIViewControllerWrapperView: 0x594cc90; ...
Superview: <UINavigationTransitionView: 0x594a420; ...
Superview: <UILayoutContainerView: 0x59469a0; ... // navigationController.view
Superview: <UIViewControllerWrapperView: 0x594b430; ...
Superview: <UITransitionView: 0x5b0e110; ...
Superview: <UILayoutContainerView: 0x5b0dc80; ... // tabBarController.view
Superview: <UIWindow: 0x5942a30; ...
строки с префиксом "Superview" были результатом ходьбы вверх по rootViewController.view's
superview цепь до попадания ноль.
тогда, конечно, быстрый взгляд на стек вызовов в пару из мест, где viewDidDisappear
будет вызываться на контроллере корневого представления.
во-первых, стек вызовов, когда viewDidDisappear
вызывается на корневом контроллере в результате нажатия нового контроллера на стек:
-[RootController viewDidDisappear:]
-[UINavigationController navigationTransitionView:didEndTransition:fromView:toView:]
...
во-вторых, стек вызовов при выборе другой вкладки в самом верхнем UITabBarController:
-[RootController viewDidDisappear:]
-[UINavigationController viewDidDisappear:]
-[UITabBarController transitionFromViewController:toViewController:transition:shouldSetSelected:]
таким образом, во всех случаях кажется, что Apple решила, что контроллеры должны вызывать различные viewDidAppear
, методы etc на их встроенные субконтроллеры и что представление должно быть встроено аналогично. Я думаю, что ОП попал в этот гвоздь прямо по голове, если мы должны взять UIKit
дизайн как хороший повод, чтобы следовать.
Я только что видел это же обстоятельство. Ранее сегмент построителя интерфейса, вызванный выбором ячейки таблицы, перестал работать, и после некоторого раздражения, копающегося в коде, я просто настроил его вручную, вызывая из переопределения выбора ячейки в делегате представления таблицы.
позже я сделал некоторые изменения макета в вызываемом контроллере представления и увидел, что viewDidAppear не вызывается, как описано выше. Выходные данные отладки ссылались на" вложенные операции push " или что-то, и так как у меня был большой комментарий к себе в моей ручной операции толчка
#warning I SHOULD NOT HAVE TO DO THIS!!
Я определил код segue и, конечно же, IB segue теперь работал, и это была моя ручная операция в коде выбора ячейки таблицы, которая испортила вызовы делегата в вызываемом представлении. Я удалил ручной код, и все снова в порядке.
Кажется странным, что код выбора ячейки вызывается после нажатия представления. Я должен сделать протокол и делегат, чтобы получить indexpath выбранной ячейки в звонящего.