the programming language apple iphone ios uiviewcontroller uinavigationcontroller

iphone - programming - swift manual



Cuando utilizo un UINavigationController, los métodos viewWillAppear o viewDidAppear de mi controlador no se llaman (4)

Es 2015 y probablemente no necesite usar los métodos UINavigationControllerDelegate como en la respuesta aceptada. Simplemente revise cuidadosamente su código si tiene algún error tipográfico o de copiar / pegar.

Me encontré con un problema últimamente que ya no se llama a viewDidAppear después de copiar / pegar. Después de leer la respuesta de @ Yar, hice una búsqueda en viewDidAppear en mi código y encontré que [super viewDidAppear:animated]; fue llamado erróneamente en viewWillAppear :

-(void)viewWillAppear:(BOOL)animated { [super viewDidAppear:animated]; //... ^^^ } - (void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; // this is never called :( }

Simplemente comparta este hallazgo aquí en caso de que las personas tengan el mismo problema.

Aquí está el tono.

  • Tengo una subclase UIViewController que hace algo en sus métodos viewWillAppear y viewDidAppear.
  • Quiero anidar este controlador de vista en un UINavigationViewController.
  • Dependiendo de la complejidad de la jerarquía de vista, los dos métodos viewWillAppear y viewDidAppear de mi controlador pueden no ser llamados.

¿Qué debo hacer entonces para asegurarme de que estos dos métodos siempre se invoquen independientemente de mi jerarquía de vistas?

Ejemplo de una jerarquía de vista "compleja":

UIViewController subclass containing a UITabBarController |_ Each tab containing a UINavigationViewController |_ Each UINavigationController controller containing a custom UIViewController

Cuando presenta TabBarController como una vista modal, se viewDidAppear métodos viewWillAppear y viewDidAppear del TabBarController pero no los de los UIViewControllers personalizados anidados en UINavigationViewControllers.


Una razón por la que esto sucederá es si anula viewDidAppear: en su subclase UINavigationController y no llama a [super viewDidAppear:animated]; ...


debe hacerse de la siguiente manera:

Ver (* 1) editar

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { CustomViewController *controller = [[CustomViewController alloc] initWithNibName:nil bundle:nil]; UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:controller]; [controller release]; self.window.rootViewController = navController; //(*1) [self.window makeKeyAndVisible]; [navController release]; return YES; }


NOTA: esto fue escrito en 2013. Los cambios en la forma en que maneja iOS las jerarquías de vista hoy en día pueden hacer que esta solución sea inútil y / o peligrosa. Entonces, utilícelo bajo su propio riesgo.

Respuesta original Al anidar un UIViewController personalizado bajo un UINavigationController, los métodos viewWillAppear y viewDidAppear del viewController personalizado pueden no ser invocados dependiendo de la complejidad de la jerarquía del controlador de vista (vistas modales, controlador de navegación dentro del controlador de vista de pestañas ...). Entonces, si te encuentras en esta situación, ¿qué puedes hacer para asegurarte de que se invoquen estos dos métodos?

La respuesta...

Use los métodos UINavigationControllerDelegate

Este es un método muy elegante de implementar, ya que no depende de ninguna suposición sobre cuándo el controlador de navegación cargará el controlador.

Hay dos métodos disponibles:

- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated - (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated

Así es como cambiaría el código.

Debe declarar que su CustomViewController implementa el protocolo UINavigationControllerDelegate:

@interface CustomViewController : UIViewController <UINavigationControllerDelegate>

Necesita configurar su CustomViewController como el delegado del UINavigationController donde lo inicializa.

Por último, también debe agregar su implementación personalizada de los métodos UINavigationControllerDelegate a su implementación de la clase CustomViewController. Por ejemplo, puede implementar el método navigationController:willShowViewController:animated: para que:

  • cuando el UINavigationController está a punto de mostrar el controlador de vista en sí, se llama a su método viewWillAppear
  • cuando el UINavigationController está a punto de mostrar otro controlador de vista, el delegado del UINavigationController se establece en este otro controlador de vista, siempre que este controlador de vista implemente el método UINavigationViewControllerDelegate.

Artículo de lista

- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated { if ([viewController isEqual:self]) { [viewController viewWillAppear:animated]; } else if ([viewController conformsToProtocol:@protocol(UINavigationControllerDelegate)]){ // Set the navigation controller delegate to the passed-in view controller and call the UINavigationViewControllerDelegate method on the new delegate. [navigationController setDelegate:(id<UINavigationControllerDelegate>)viewController]; [[navigationController delegate] navigationController:navigationController willShowViewController:viewController animated:YES]; } }

Y el navigationController:didShowViewController:animated: se puede implementar de la siguiente manera:

- (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated { if ([viewController isEqual:self]) { [self viewDidAppear:animated]; } }

El beneficio de este enfoque es que usted confía únicamente en la forma en que se supone que UINavigationViewController debe funcionar y realiza sus llamadas justo en el momento correcto. También le permite pasar la delegación a medida que sube y baja la jerarquía del controlador de navegación justo antes de que se llame al método viewWillAppear.

Nuevamente para una jerarquía simple esto puede no ser requerido. Pero si alguna vez te encuentras en una situación en la que no se viewWillAppear viewDidAppear métodos viewWillAppear y viewDidAppear , ahora sabes qué hacer ...