2009-12-20 12 views
9

Suponiendo que cargue un controlador de vista desde una punta y decida hacer algo con una de sus subvistas detrás de la escena. En un momento posterior en el tiempo, mostraría la vista de este controlador de vista.Hacer una vista (inicializado desde initWithNibName) cargar toda su subvista

viewController = [[MyViewController alloc] initWithNibName:@"MyViewController" bundle:nil]; 
[viewController.someSubview doSomething]; 

//later on 
[mainView addSubview:viewController.view]; 

El problema es que, no parece el objeto someSubview para ser cargado hasta que aparezca la vista, por lo que el doSomething método no se llama. Hasta ahora mi solución alternativa es llamar a:

[mainView addSubview:viewController.view]; 
[viewController.view removeFromSuperview]; 

para inicializar primero las subvistas de viewcontroller. ¿Hay alguna manera más elegante (como un método loadSubviews o algo así) para esta tarea?

Respuesta

23

En primer lugar me gustaría probar simplemente accediendo a la propiedad:

[viewController view]; 

Esto obligará a la carga lenta de la vista (y por lo tanto los subvistas y puntos de venta, etc.) y esto podría ser suficiente para usted. Los controladores de vista de forma predeterminada no cargarán su vista hasta que acceda a ella, por lo que es posible que este sea el motivo por el que está viendo un retraso.

Forzar una carga como esta suele ser la solución cuando intenta acceder a una propiedad de un outlet, pero no se ha enlazado aún, como someSubview en su caso.

También puede mejorar un poco las cosas mediante la adición de la vista, pero lo que es oculto:

viewController.view.hidden = YES; 
[mainView addSubview:viewController.view]; 

A continuación, en lugar de llamar addSubview cuando se quiere mostrar, simplemente hacer:

viewController.view.hidden = NO; 

I He usado este método al animar en vistas usando las transiciones UIViewAnimationTransitionFlipFromRight etc. Incluso cuando se fuerza una carga lenta de la vista, todavía hay un retraso notable, así que lo he usado un poco para mejorar el rendimiento.

+0

Gracias, que lo hizo. – iamj4de

+0

@MarkAmery Apple le dice explícitamente que no llame a -loadView en la documentación: "Nunca debe llamar a este método directamente. El controlador de vista llama a este método cuando se solicita su propiedad de vista pero actualmente es nula. Este método carga o crea una vista y lo asigna a la propiedad de vista ". –

+0

@MikeWeller Buen punto: no había revisado la documentación lo suficiente como para saberlo. Supongo que tenemos que elegir entre uno de dos hacks ligeramente feos, entonces. Por mi parte, probablemente me apegue a 'loadView' solo porque es más explícito, pero reconozco que no es la solución limpia que pensé que era. –

0

IOS 9 introdujo -(void) loadViewIfNeeded

utilizo

if ([_myVC respondsToSelector:@selector(loadViewIfNeeded)]) { 
    [_myVC loadViewIfNeeded]; 
} else { 
    [_myVC view]; 
} 
Cuestiones relacionadas