2010-08-24 16 views
36

viewWillAppear, viewDidAppear no está llamando, no disparando

Síntoma (Esto es a la vez de preguntas y respuestas, ya que tomó un poco de excavación para encontrar la verdadera respuesta.): viewWillAppear, viewDidAppear no estaban siendo llamados en mi UIViewController .

Causa: La incorporación de un UINavigationController o UITabBarController (mi caso) en un UIViewController alguna manera interrumpe con la vocación de estos métodos.

Solución: Llámelos manualmente en el UIViewController que contiene el UINavigationController/UITabBarController antes mencionado.

Por ejemplo (asumiendo projectNavigationController es su 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 tuve un interior UITabBarController y me llamaron a los métodos en consecuencia y todo se resolvió.

(Atribución de la solución: http://davidebenini.it/2009/01/03/viewwillappear-not-being-called-inside-a-uinavigationcontroller/)

+1

solo porque tengo curiosidad ...: ¿por qué envolver un controlador de barra de pestañas en otro controlador de vista? :) en la mayoría de los casos, son la raíz de la jerarquía de la vista (controlador) ... – Toastor

+0

+1 .. realmente resolvió mi problema .. aplausos –

Respuesta

9

voy a seguir adelante y estar de acuerdo con @ St3fan, y utilizar UIKit como el ejemplo contrario.

Sin embargo, la sabiduría (o la falta de ella) de los controladores de inclusión en general debe guiarse por principios de diseño de IU.

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.

yo era lo suficientemente curioso que molestarse en comprobar lo que hacen con los puntos de vista (añadir a la vista "super-controlador" o al UIWindow. Estaba bastante seguro de que iba a encontrar que los puntos de vista sub-controlador eran descendientes de las vistas de supercontrolador en la jerarquía de vista, lo cual es contrario a la recomendación de St3fan.

Arranqué 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 simple ole UIViewController como su controlador de vista raíz, y una segunda pestaña con un simple viejo UIViewController solo para que tuviera una segunda pestaña para hacer clic más adelante.

Espolvorear en algunos NSLog declaraciones a la salida 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" eran la salida desde recorriendo la cadena de rootViewController.view's supervista hasta golpear nula.

Luego, por supuesto, un vistazo rápido a la pila de llamadas en un par de lugares donde se llamaría viewDidDisappear en el controlador de vista raíz.

En primer lugar, la pila de llamadas cuando viewDidDisappear se llama en el controlador de la raíz como resultado de un nuevo controlador de ser empujado en la pila:

-[RootController viewDidDisappear:] 
-[UINavigationController navigationTransitionView:didEndTransition:fromView:toView:] 
... 

En segundo lugar, la pila de llamadas cuando otra pestaña se selecciona en el de más arriba UITabBarController:

-[RootController viewDidDisappear:] 
-[UINavigationController viewDidDisappear:] 
-[UITabBarController transitionFromViewController:toViewController:transition:shouldSetSelected:] 

lo tanto, en todos los casos, parece que Apple ha decidido que los controladores deben estar llamando los distintos viewDidAppear, métodos, etc en sus sub-controladores embebidos y que de la vista deben insertarse similares ly. Creo que el OP golpeó este clavo justo en la cabeza si tomamos el diseño UIKit como una buena pista para seguir.

+0

Análisis de interés imaginaryboy. Aprecio tu POV St3fan. En las configuraciones típicas, se agrega a la ventana el UITabBarController (que tiene sus propios controles de navegación y controladores de vista). Es muy fácil ver esto. Sin embargo, mi situación era ligeramente diferente. En mi caso, el usuario ingresa a un modo específico de la aplicación a través de un modal. En este otro modo, hay un UITabBarController diferente del que el usuario ve originalmente. Tal vez podría haber llamado al delegado de la aplicación para agregar el nuevo UITabBarcontroller a la ventana (?) Pero agregarlo al UIViewController modal fue más fácil. – pschang

0

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 describe anteriormente. El resultado de la depuración hecho referencia a "operaciones de empuje anidados" o algo así, y ya que tenía un gran comentario a mí mismo en mi operación de empuje manual de

#warning I SHOULD NOT HAVE TO DO THIS!!

I breakpointed el código segue y, por supuesto, la segue IB Ahora estaba funcionando, y era mi operación manual en el código de selección de celda de 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.

Cuestiones relacionadas