iphone - containerview - viewWillAppear, viewDidAppear no se llama, no se activa
view controller que es (2)
(Esto es tanto una pregunta como una respuesta, ya que fue necesario investigar un poco para encontrar la respuesta real).
Síntoma: viewWillAppear
, viewDidAppear
no se llamaban en mi UIViewController.
Causa: Incrustar un UINavigationController
o UITabBarController
(mi caso) en un UIViewController
alguna manera interrumpe con la llamada de estos métodos.
Solución: UIViewController
manualmente en el UIViewController
que contiene el UINavigationController
/ UITabBarController
antes mencionado.
Por ejemplo (suponiendo que projectNavigationController
es tu 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]; }
En mi caso, tenía un UITabBarController
interno y llamé a los métodos en consecuencia y todo se resolvió.
(Atribución en la solución: http://davidebenini.it/2009/01/03/viewwillappear-not-being-called-inside-a-uinavigationcontroller/ )
Acabo de ver esta misma circunstancia. Anteriormente, el segue del generador de interfaz desencadenado por una selección de celda de tabla había dejado de funcionar y después de exasperar el código, simplemente lo configuré manualmente, llamando desde la anulación de selección de celda en el delegado de vista de tabla.
Más tarde hice algunos cambios de diseño en el controlador de vista llamado y vi que viewDidAppear no se llamaba, como se describió anteriormente. La salida de depuración hizo referencia a "operaciones de inserción anidadas" o algo así, y como tuve un gran comentario para mí en mi operación de inserción manual
#warning I SHOULD NOT HAVE TO DO THIS!!
Decidí romper el código segue y, efectivamente, el segue de IB ahora estaba funcionando, y era mi operación manual en el código de selección de celda de la tabla lo que estaba estropeando las llamadas de delegado en la vista llamada. Eliminé el código del manual y todo vuelve a estar bien.
Parece extraño que se llame al código de selección de celda después de presionar la vista. Tengo que hacer un protocolo y delegar para obtener la ruta de índice de la celda seleccionada en la persona que llama.
Voy a seguir adelante y no estoy de acuerdo con @ St3fan, y usar UIKit
como contraejemplo.
Sin embargo, la sabiduría (o falta de ella) de los controladores de inclusión en general debe guiarse por principios de diseño de interfaz de usuario sensato.
El contraejemplo más fácil es UINavigationControllers
incrustado en UITabBarControllers
. Estos aparecen por todo el lugar. Justo en la parte superior de mi cabeza, la aplicación iPod en iPhone, y Contactos dentro de la aplicación Teléfono en iPhone.
Tenía curiosidad suficiente como para molestarme en comprobar lo que hacen con las vistas (agregar a la vista de "supercontrolador" o a la UIWindow
. Estaba bastante seguro de que iba a encontrar que las vistas del subcontrolador eran descendientes del super- vistas de controlador en la jerarquía de vista, lo cual es contrario a la recomendación de St3fan.
UITabBarController
una aplicación de iPhone muy rápida conectando todo en InterfaceBuilder para crear una aplicación basada en UITabBarController
con dos pestañas, la primera de las cuales era un UINavigationController
con un UIViewController
como su controlador de vista raíz, y una segunda pestaña con un viejo UIViewController
así que tuve una segunda pestaña para hacer clic más adelante.
Espolvorear en algunas declaraciones NSLog
para mostrar los diversos UIView''s
para los controladores que vemos esto:
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; ...
Las líneas con el prefijo "Superview" fueron el resultado de recorrer la rootViewController.view''s
superview rootViewController.view''s
rootViewController.view hasta llegar a nil.
Luego, por supuesto, un vistazo rápido a la pila de llamadas en un par de lugares donde se viewDidDisappear
en el controlador de la vista raíz.
En primer lugar, la pila de llamadas cuando se llama a viewDidDisappear
en el controlador raíz como resultado de la viewDidDisappear
de un nuevo controlador en la pila:
-[RootController viewDidDisappear:]
-[UINavigationController navigationTransitionView:didEndTransition:fromView:toView:]
...
En segundo lugar, la pila de llamadas cuando se selecciona otra pestaña en el UITabBarController superior:
-[RootController viewDidDisappear:]
-[UINavigationController viewDidDisappear:]
-[UITabBarController transitionFromViewController:toViewController:transition:shouldSetSelected:]
Entonces, en todos los casos, parece que Apple decidió que los controladores deberían llamar a los diversos métodos viewDidAppear
, etc. en sus subcontroladores integrados y que la vista debería incrustarse de manera similar. Creo que el OP golpeó este clavo en la cabeza si tomamos el diseño de UIKit
como una buena pista para seguir.