¿Dónde debo establecer las restricciones de reproducción automática al crear vistas de forma programática?

Veo diferentes ejemplos donde se establecen restricciones. Algunos los configuran en viewDidLoad / loadView (después de agregar la subvista). Otros los configuran en el método updateViewConstraints , que es llamado por viewDidAppear .

Cuando bash establecer restricciones en updateViewContraints , puede haber un salto en el layout, por ejemplo, un ligero retraso antes de que aparezca la vista. Además, si utilizo este método, ¿debo eliminar las restricciones existentes primero, es decir [self.view [removeConstraints:self.view.constraints] ?

Configuré mis restricciones en viewDidLoad / loadView (estoy apuntando a iOS> = 6). updateViewConstraints es útil para cambiar valores de restricciones, por ejemplo, si alguna restricción depende de la orientación de la pantalla (lo sé, es una mala práctica), puede cambiar su constant en este método.

Agregar restricciones en viewDidLoad se muestra durante la session "Introducción al layout automático para iOS y OS X" (WWDC 2012), a partir de 39:22. Creo que es una de esas cosas que se dicen durante las conferencias, pero no aterrizan en la documentation.

ACTUALIZACIÓN: noté la mención de configurar restricciones en la administración de resources en los controlleres de vista :

Si prefiere crear vistas mediante progtwigción, en lugar de utilizar un guión gráfico, lo hace anulando el método loadView del controller de loadView . Su implementación de este método debe hacer lo siguiente:

(…)

3.Si está utilizando el layout automático, asigne suficientes restricciones a cada una de las vistas que acaba de crear para controlar la position y el tamaño de sus vistas . De lo contrario, implemente los methods viewWillLayoutSubviews y viewDidLayoutSubviews para ajustar los frameworks de las subvistas en la jerarquía de vistas. Consulte "Cambiar el tamaño de las vistas del controller de la vista".

ACTUALIZACIÓN 2 : Durante la WWDC 2015, Apple dio una nueva explicación sobre el uso recomendado de updateConstraints y updateViewConstraints :

En realidad, todo esto es una forma de que las vistas tengan la oportunidad de hacer cambios a las restricciones justo a time para el siguiente pase de layout, pero a menudo no es realmente necesario.

Toda la configuration de restricción inicial debería ocurrir idealmente dentro de Interface Builder.

O si realmente encuentra que necesita asignar sus restricciones mediante progtwigción, algún lugar como viewDidLoad es mucho mejor.

Las restricciones de actualización son realmente solo para trabajos que deben repetirse periódicamente.

Además, es bastante sencillo simplemente cambiar las restricciones cuando encuentras la necesidad de hacer eso; mientras que, si toma esa lógica aparte del otro código que está relacionado con él y lo mueve a un método separado que se ejecuta más tarde, su código se vuelve mucho más difícil de seguir, por lo que le será más difícil mantener , será mucho más difícil de entender para otras personas.

Entonces, ¿cuándo necesitarías usar restricciones de actualización?

Bueno, se networkinguce al performance.

Si descubre que solo cambiar las restricciones en su lugar es demasiado lento, entonces las restricciones de actualización podrían ayudarlo.

Resulta que cambiar una restricción dentro de las restricciones de actualización es realmente más rápido que cambiar una restricción en otras ocasiones.

La razón de esto es porque el motor puede tratar todos los cambios de restricción que ocurren en este pase como un lote.

Recomiendo crear un BOOL y establecerlos en -updateConstraints de UIView (o -updateViewConstraints , para UIViewController).

-[UIView updateConstraints] : (docs de apple)

Las vistas personalizadas que configuran las propias restricciones deberían hacerlo anulando este método.

Tanto -updateConstraints como -updateViewConstraints se pueden llamar varias veces durante la vida de una vista. (Llamar a setNeedsUpdateConstraints en una vista hará que esto suceda, por ejemplo). Como resultado, debe asegurarse de evitar la creación y activación de restricciones duplicadas, ya sea utilizando un BOOL para realizar solo ciertas configuraciones de restricciones solo una vez, o al hacer Asegúrese de desactivar / eliminar las restricciones existentes antes de crear y activar otras 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 para señalar que los documentos de Apple recomiendan llamar a super como el último paso. Si llama a super antes de hacer cambios a algunas restricciones, puede golpear una exception de time de ejecución (locking).

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 cualquier retraso 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! } 

Puede configurarlos en viewWillLayoutSubviews: también:

  override func viewWillLayoutSubviews() { if(!wasViewLoaded){ wasViewLoaded = true //update constraint //also maybe add a subview } } 

Hazlo a la vista del método de subidas de layout

 override func viewDidLayoutSubviews() { super.viewDidLayoutSubviews() }