2011-09-11 11 views
5

Quiero configurar un UIViewController dentro de un NavigationController mediante programación, sin embargo, se llama al método loadView o viewDidLoad.loadView de UIViewController no se llama

Este es mi código en el delegado de la aplicación:

MyViewController *viewController = [[MyViewController alloc] init]; 
UIView *view = [[UIView alloc] initWithFrame:window.frame]; 
viewController.view = view; 

UINavgationController *navController = [[UINavigationController alloc] initWithRootViewController:viewController]; 

[window addSubview:[navController view]; 
[window makeKeyAndVisible]; 

Cuando inicio la aplicación veo un navigationbar, pero no hay llamadas a loadView. ¿Qué me estoy perdiendo? pensé loadView se llama después de llamar view

Editar

MyViewController *viewController = [[MyViewController alloc] init]; 
[viewController view]; // doesn't look right? 

UINavgationController *navController = [[UINavigationController alloc] initWithRootViewController:viewController]; 

[window addSubview:[navController view]; 
[window makeKeyAndVisible]; 

editado hacia el comentario de Jonás, pero loadView todavía no se consiga llamar.

Respuesta

10

A UIViewController creará su vista (por cargarlo desde una punta o la aplicación de -loadView) cuando view getter del controlador se llama y su vista es actualmente nil.

En el código que se muestra, nunca invocará el getter de la propiedad view, solo su setter.

Además, está asignando la vista del controlador desde el delegado de su aplicación. UIViewController s se espera que creen sus propias vistas a pedido, no las proporcione alguna otra clase. Este enfoque le causará problemas más adelante cuando se dé cuenta de que el controlador descarga su vista e intenta recrearlo en respuesta a las advertencias de memoria. Deje que su controlador cree su vista, no intente pasarlo.

+0

En cuanto a su segunda observación, la asignación de la vista, se refiere a mi segunda y tercera línea de código, ¿verdad? Eso tiene sentido. ¿Pero cómo llamaría al getter en este caso? –

+0

'[viewController view]' invoca el getter de la vista, pero no debería ser necesario que lo haga directamente. El 'UINavigationController' al que agregó su controlador de vista llamará a ese getter en algún momento para agregar la vista de su controlador a la jerarquía de vista. ¿Puedes compartir tu implementación del controlador de vista? Parece que tienes algo más en juego. – Jonah

+0

Básicamente es la plantilla UIViewController vacía de Xcode, pero no se llama a ningún método (vista) además de init. Ahí traté de configurar una vista como esta: - (id) init { \t self ((self = [super init])) { \t UIView * view = [[UIView alloc] initWithFrame: [[UIScreen mainScreen] bounds] ]; \t self.view = view; \t [ver versión]; \t} return self; } –

2

tal vez no enfrentaste este problema ... pero el otro día encontré el mismo problema irritante .. loadView, viewDidLoad y viewWillAppear no me llamaron en mi UIViewController.

Mi problema era v. Simple pero un poco difícil de atrapar si no tiene mucho cuidado. En lugar de escribir

-(void) loadView 

escribí:

-(void) loadview 

Tenga en cuenta que esto no se disparará ninguna advertencia. La diferencia de "V" y "v" en loadView se puede perder fácilmente. Y, obviamente, dado que loadView no se llamó, viewDidLoad/viewWillAppear tampoco se llamará, ya que no se cargó ninguna vista (no estoy usando ninguna semilla ... creando la vista programáticamente).

-Anshu

2

Otra Gotcha digno de mención es si se define un

@synthesize view; 

sin @property coincidente en su aplicación, esto puede dar lugar a llamadas a cero de regresar de su controlador de vista, y no hay ninguna llamada a su método loadView.

+1

Aha! Este me atrapó. Terminé con una "vista @synthesize" en una clase debido a una operación de búsqueda/reemplazo demasiado entusiasta, no me di cuenta, y de repente mi vista quedó completamente en blanco porque nunca se llamó a loadView. Esto fue difícil de rastrear. ¡Gracias! –