Con las contraintencias de layout iOS, ¿es posible queuepsar entre tags cuando la altura es 0?

Considere una vista que contenga tres UILabel s con contrabashs verticales definidos de la siguiente manera:

 [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[label1]-2-[label2]-2-[label3]" options:0 metrics:nil views:views]]; 

Esto generará un layout con las tags astackdas verticalmente con relleno de 2px entre cada label.

En mi aplicación, a veces el text que se muestra en una o más de las tags es nulo (o en blanco) lo que significa que el marco de la label termina con altura == 0. En este caso, quiero que el relleno de 2px entre la label de 0 altura sea queuepsado

Cuando todas las tags tienen un valor de text, quiero que el layout sea:

label1 text
[2px]
text label2
[2px]
text label3

Cuando label2 tiene un valor de text nulo, quiero que el layout sea:

label1 text
[2px]
text label3

En este último caso, la label 2 todavía está allí, pero tiene una altura de 0 y su relleno de 2px se ha contraído.

Pregunta : ¿Es esto posible? ¿Cómo definiría las restricciones para lograr esto?

EDITAR

Me doy count de que es posible implementar el relleno (inserción de borde) en una subclass de UILabel y quitar el relleno de las restricciones. Puedo ir por esa ruta, solo con la esperanza de que haya una forma de definir el queuepso de este relleno en la definición de restricción.

Puede networkingefinir sus restricciones cuando cambian los valores que está mostrando en sus tags.

Si se trata de una subclass de vista con tres properties de cadena, en el setter de cada propiedad, puede llamar a setNeedsUpdateConstraints .

Luego, en su implementación updateConstraints , elimine las restricciones creadas anteriormente (que puede almacenar en una propiedad si es necesario, ya que el método VFL devuelve una matriz) y regenere las apropiadas.

Si está en un controller de vista que está manejando el layout, hay un método análogo para actualizar las restricciones en la vista del controller de vista: updateViewConstraints .

Sí, hay una manera de hacer esto, y debes tratar esto modificando tus restricciones en lugar de jugar con una subclass UILabel . Sin embargo, es un poco complicado hacer uso de VFL como lo está haciendo actualmente, porque lo que necesita hacer es tener una reference a las restricciones individuales entre cada label, y VFL devuelve una serie de restricciones (por lo que no sabrá cuál es cual).

Entonces, suponiendo que no esté usando VFL, querrá crear las restricciones entre cada par de tags individualmente y almacenarlas en un ivar o en una propiedad:

 NSLayoutConstraint *label1To2Constraint = [NSLayoutConstraint constraintWith...]; NSLayoutConstraint *label2To3Constraint = [NSLayoutConstraint constraintWith...]; 

Si no agrega explícitamente restricciones para establecer una altura fija en las tags (el código VFL que está utilizando no lo hace), entonces si la label no tiene text, se networkingucirá a cero. Entonces, ahora todo lo que necesita hacer es actualizar el text de las tags, verificar si las tags tienen text o no y actualizar la propiedad constant de la restricción entre cada par según sea necesario:

 BOOL hasLabel1Text = label1.text.length > 0; BOOL hasLabel2Text = label2.text.length > 0; BOOL hasLabel3Text = label3.text.length > 0; label1To2Constraint.constant = (hasLabel1Text && hasLabel2Text) ? 2.0f : 0.0f; label2To3Constraint.constant = (hasLabel2Text && hasLabel3Text) ? 2.0f : 0.0f; 

Cambiar la constant de las restricciones existentes puede (y debería) realizarse sin eliminar y volver a agregar la restricción. Es muy eficiente (Eliminar y volver a agregar restricciones es mucho más gravoso en el motor de layout automático interno, y debe evitarse lo más posible).

Para salvarte un poco de dolor, me gustaría UIView+AutoLayout hacia la categoría UIView+AutoLayout que he creado. Te prometo que mejorará drásticamente tu experiencia con Auto Layout utilizando la capa más delgada posible de código de terceros. Verá que es muy fácil crear las restricciones que necesita para este escenario.

Esto funciona bien para este tipo de problema: https://github.com/depth42/AutolayoutExtensions