¿Cómo funciona la contención de View Controller en iOS 5?
uiviewcontroller ios5 (2)
Esta parte no es correcta:
[vc willMoveToParentViewController:self];
[self addChildViewController:vc];
[self.view addSubview:vc.view]; // or something like this.
[vc didMoveToParentViewController:self];
De acuerdo con los documentos:
Cuando el contenedor personalizado llama al método addChildViewController: llama automáticamente al método willMoveToParentViewController: del controlador de vista para agregarlo como elemento secundario antes de agregarlo.
Por lo tanto, no necesita la [vc willMoveToParentViewController:self]
. Se realiza automáticamente cuando llamas [self addChildViewController:vc]
. Aquí está la muestra del código nuevamente:
[self addChildViewController:vc];
// [vc willMoveToParentViewController:self] called automatically
[self.view addSubview:vc.view]; // or something like this.
[vc didMoveToParentViewController:self];
Para eliminar los controladores de vista:
El método removeFromParentViewController llama automáticamente al método didMoveToParentViewController: del controlador de vista secundaria después de eliminar el elemento secundario.
Presumiblemente, esta llamada es [oldVC didMoveToParentViewController:nil]
.
[vc willMoveToParentViewController:nil];
[vc.view removeFromSuperview];
[vc removeFromParentViewController];
// [vc didMoveToParentViewController:nil] called automatically
En la sesión 102 de la WWDC 2011, Apple introdujo la Contención del controlador de vista, que es la capacidad de crear contenedores de controlador de vista personalizados, análogos a UITabBarController
, UINavigationController
y similares.
Vi los ejemplos varias veces. Hay una ráfaga de métodos asociados con este patrón, pero fue un poco difícil de resolver exactamente. Voy a publicar aquí lo que creo que está sucediendo y ver si la comunidad confirmará o confirmará mis sospechas.
Escenario 1: pasar de no padre a un nuevo controlador de vista padre
[vc willMoveToParentViewController:self];
[self addChildViewController:vc];
[self.view addSubview:vc.view]; // or something like this.
[vc didMoveToParentViewController:self];
¿Deben aparecer las dos primeras líneas en el orden dado o pueden invertirse?
Escenario 2: pasar de un controlador de vista principal a ningún controlador de vista principal
[vc willMoveToParentViewController:nil];
[vc.view removeFromSuperview];
[vc removeFromParentViewController];
¿También es necesario llamar a [vc didMoveToParentViewController:nil]
? Los ejemplos en la Sesión 102 no hicieron esto en este escenario, pero no sé si eso fue una omisión o no.
Escenario 3: pasar de un controlador de vista principal a otro
Esto probablemente ocurrirá de la siguiente manera, porque la lógica en cada controlador de vista padre estará encapsulada.
// In the old parent
[vc willMoveToParentViewController:nil];
[vc.view removeFromSuperview];
[vc removeFromParentViewController];
// In the new parent
[vc willMoveToParentViewController:self];
[self addChildViewController:vc];
[self.view addSubview:vc.view];
[vc didMoveToParentViewController:self];
Preguntas
Mi pregunta principal es esta: ¿Es así como debería funcionar la contención del controlador de vista, en general? ¿Son correctos los mecanismos anteriores?
¿Es necesario llamar a willMoveToParentViewController
antes de llamar a addChildViewController
? Esto me parece el orden lógico, pero ¿es estrictamente necesario?
¿Es necesario llamar a didMoveToParentViewController:nil
después de llamar a removeFromParentViewController
?
Los documentos UIViewController
son bastante claros sobre cuándo y cuándo no llamar a los métodos willMove
/ didMove
. Consulte la documentación "Implementación de un controlador de vista de contenedor" .
Los documentos dicen que si no anula addChildViewController
, no tiene que llamar willMoveToParentViewController:
método willMoveToParentViewController:
Sin embargo, debe llamar al método didMoveToParentViewController:
vez completada la transición. "Del mismo modo, es responsabilidad del controlador de vista contenedor llamar al método willMoveToParentViewController:
antes de llamar al método removeFromParentViewController
. El método removeFromParentViewController
llama al método didMoveToParentViewController:
del controlador de vista hijo."
Además, hay un ejemplo resuelto here y código de ejemplo here .
Buena suerte