Pregunta Ver cambios de marco entre viewWillAppear: y viewDidAppear:


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

-(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 = <NSArray: 0x10580100>; layer = <CALayer: 0x1057f210>; contentOffset: {0, 0}>
MyApp[61880:c07] <UIScrollView: 0x1057eff0; frame = (0 44; 320 416); clipsToBounds = YES; autoresize = TM+BM; gestureRecognizers = <NSArray: 0x10580100>; layer = <CALayer: 0x1057f210>; 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 viewDidLoad método, pero si el contenido no está disponible para que yo cambie hasta que aparezca en la pantalla, eso parece bastante inútil. ¿Qué podría estar pasando?


73
2017-07-14 07:50


origen


Respuestas:


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 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 volver a calcular 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. Trate de preguntar lo mismo inmediatamente después de súper - (void)viewDidLayoutSubviews método 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.


94
2017-07-14 09:46



Desde el 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 están configurados en viewWillAppear:

El método apropiado para modifique 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.


142
2017-07-14 09:06



llamada

self.scrollView.layoutIfNeeded ()

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


6
2017-10-11 11:45



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).


0
2018-05-28 00:11