Veo diferentes ejemplos donde se establecen restricciones. Algunos los establecen en viewDidLoad
/ loadView
(después de que se agregó la subvista). Otros los configuran en el método updateViewConstraints
, que es llamado por viewDidAppear
.
Cuando intento establecer restricciones, updateViewContraints
puede haber un salto en el diseño, por ejemplo, un ligero retraso antes de que aparezca la vista. Además, si utilizo este método, ¿debo eliminar primero las restricciones existentes, es decir [self.view [removeConstraints:self.view.constraints]
?
ios
cocoa-touch
autolayout
Heisenberg
fuente
fuente
updateViewConstraints
: Puede anular este método en una subclase para agregar restricciones a la vista o sus subvistas. (de los documentos de Apple )Respuestas:
Configuré mis restricciones en
viewDidLoad
/loadView
(me dirijo a iOS> = 6).updateViewConstraints
es útil para cambiar los valores de las restricciones, por ejemplo, si alguna restricción depende de la orientación de la pantalla (lo sé, es una mala práctica), puede cambiarlaconstant
en este método.La adición de restricciones
viewDidLoad
se muestra durante la sesión "Introducción al diseño automático para iOS y OS X" (WWDC 2012), a partir de las 39:22. Creo que es una de esas cosas que se dicen durante las conferencias pero que no llegan a la documentación.ACTUALIZACIÓN: He notado la mención de configurar restricciones en la Gestión de recursos en los Controladores de vista :
ACTUALIZACIÓN 2 : Durante la WWDC 2015 de Apple dio una nueva explicación de
updateConstraints
yupdateViewConstraints
uso recomendado:fuente
@"|-[button1]-[button2]-|"
en ViewController, ¿verdad? ¿O hay una forma diferente?updateViewConstraints
?Recomiendo crear un BOOL y configurarlo en
-updateConstraints
UIView (o-updateViewConstraints
, para UIViewController).-[UIView updateConstraints]
: (documentos de Apple)Ambos
-updateConstraints
y-updateViewConstraints
se pueden llamar varias veces durante la vida de una vista. (LlamarsetNeedsUpdateConstraints
a una vista provocará que esto suceda, por ejemplo). Como resultado, debe asegurarse de evitar la creación y activación de restricciones duplicadas, ya sea usando un BOOL para realizar una configuración de restricción determinada solo una vez, o asegurándose de para desactivar / eliminar restricciones existentes antes de crear y activar nuevas.Por ejemplo:
- (void)updateConstraints { // for view controllers, use -updateViewConstraints if (!_hasLoadedConstraints) { _hasLoadedConstraints = YES; // create your constraints } [super updateConstraints]; }
Saludos a @fresidue en los comentarios por señalar que los documentos de Apple recomiendan llamar
super
como último paso. Si llamasuper
antes de realizar cambios en algunas restricciones, puede encontrar una excepción en tiempo de ejecución (bloqueo).fuente
-updateConstraints
ni nada, todavía se llamaría y usted todavía llama[super updateConstraints]
.super
al final de su implementación de-updateConstraints
o-updateViewConstraints
. Consulte este comentario para obtener más información.Esto debe hacerse en ViewDidLoad, según el video WWDC de Apple y la documentación.
No tengo idea de por qué la gente recomienda updateConstraints. Si lo hace en updateConstraints, tendrá problemas con NSAutoresizingMaskLayoutConstraint con cambio de tamaño automático porque sus vistas ya han tenido en cuenta las máscaras automáticas. Debería eliminarlos en updateConstraints para que funcione.
UpdateConstraints debería ser solo para eso, cuando necesite 'actualizarlos', hacer cambios, etc.desde su configuración inicial.
fuente
Hágalo a la vista hizo el método de subvistas de diseño
override func viewDidLayoutSubviews() { super.viewDidLayoutSubviews() }
fuente
Tengo esta solución para cambiar las restricciones antes de que se carguen los que están en el guión gráfico. Esta solución elimina los retrasos después de que se carga la vista.
-(void)updateViewConstraints{ dispatch_async(dispatch_get_main_queue(), ^{ //Modify here your Constraint -> Activate the new constraint and deactivate the old one self.yourContraintA.active = true; self.yourContraintB.active= false; //ecc.. }); [super updateViewConstraints]; // This must be the last thing that you do here -> if! ->Crash! }
fuente
También puede configurarlos en viewWillLayoutSubviews :
override func viewWillLayoutSubviews() { if(!wasViewLoaded){ wasViewLoaded = true //update constraint //also maybe add a subview } }
fuente
Esto funcionó para mí:
Rápido 4.2
override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) // Modify your constraints in here ... }
Aunque sinceramente no estoy seguro de que valga la pena. Parece un poco más lento de cargar que en viewDidLoad (). Solo quería sacarlos de este último, porque se está volviendo masivo.
fuente
El siguiente ejemplo es pasar cualquier vista a otra clase. crear mi vista desde el guión gráfico
Swift 5.0
override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) DispatchQueue.main.async { self.abcInstance = ABC(frame: self.myView.frame) } }
fuente