Ver cambios de marco entre viewWillAppear: y viewDidAppear:

He descubierto un comportamiento extraño en mi aplicación, donde un IBOutlet conectado tiene su marco de vista conectado entre las llamadas en mi controlador de vista para ver viewWillAppear: y viewDidAppear: Aquí está el código relevante en mi subclase UIViewController :

 -(void)viewWillAppear:(BOOL)animated { NSLog(@"%@", self.scrollView); } -(void)viewDidAppear:(BOOL)animated { NSLog(@"%@", self.scrollView); } 

y la salida de registro resultante:

 MyApp[61880:c07] <UIScrollView: 0x1057eff0; frame = (0 0; 0 0); clipsToBounds = YES; autoresize = TM+BM; gestureRecognizers = ; layer = ; contentOffset: {0, 0}> MyApp[61880:c07] <UIScrollView: 0x1057eff0; frame = (0 44; 320 416); clipsToBounds = YES; autoresize = TM+BM; gestureRecognizers = ; layer = ; contentOffset: {0, 0}> 

Lo cual muestra claramente que el marco está cambiando entre las dos llamadas. Quería hacer la configuración con la vista en el método viewDidLoad , pero si el contenido no está disponible para que cambie hasta que viewDidLoad en la pantalla, parece bastante inútil. ¿Qué podría estar pasando?

Autolayout hizo un gran cambio en la forma en que diseñamos y desarrollamos la GUI de nuestros puntos de vista. Una de las principales diferencias es que el autolayout no cambia nuestros tamaños de vista de inmediato, sino solo cuando se activa, es decir, en un momento específico, pero podemos forzarlo a recalcular nuestras restricciones de inmediato o marcarlas como “en necesidad” de diseño. . Funciona como -setNeedDisplay .
El gran desafío para mí fue comprender y aceptar eso, ya no necesitamos usar máscaras de realineamiento, y el marco se ha convertido en una propiedad inútil al colocar nuestros puntos de vista. Ya no necesitamos pensar en ver la posición, pero deberíamos pensar cómo queremos verlos en un espacio relacionado entre sí.
Cuando queremos mezclar una vieja máscara de aumento automático y el diseño automático es cuando surgen problemas. Deberíamos pensar en la implementación de autolayout muy pronto y tratar de evitar mezclar el viejo enfoque en una jerarquía de vistas basada en el diseño automático.
Está bien tener una vista de contenedor que use solo máscaras de aumento de tamaño, como una vista principal de un controlador de vista, pero es mejor si no intentamos mezclar.
Nunca usé el guión gráfico, pero lo más probable es que sea correcto. Usando Autolayout, el marco de sus vistas se establece cuando el motor de autodiseño comienza su cálculo. Intente hacer lo mismo inmediatamente después del método super - (void)viewDidLayoutSubviews de su controlador de vista.
Se llama a este método cuando el motor de autodiseño ha terminado para calcular los marcos de sus vistas.

De la documentación:

 viewWillAppear: 

Notifica al controlador de vista que su vista está a punto de agregarse a una jerarquía de vistas.

 viewDidAppear: 

Notifica al controlador de vista que su vista se agregó a una jerarquía de vista.

Como resultado, los marcos de las subvistas aún no se han establecido en viewWillAppear :

El método apropiado para modificar su UI antes de que la vista se presente en la pantalla es:

 viewDidLayoutSubviews 

Notifica al controlador de vista que su vista acaba de presentar sus subvistas.

llamada

self.scrollView.layoutIfNeeded ()

en su método viewWillAppear . Luego puede acceder a su marco y tendrá el mismo valor que imprime en viewDidAppear

En mi caso, mover todos los métodos relacionados con marcos a

 override func viewWillLayoutSubviews() 

funcionó perfectamente (estaba intentando modificar las restricciones del guión gráfico).