iOS: Etiqueta UILabel multilínea en Diseño automático


Estoy teniendo problemas tratando de lograr un comportamiento de diseño muy básico con Auto Layout. Mi controlador de vista se ve así en IB:

introduzca la descripción de la imagen aquí

La etiqueta superior es la etiqueta del título, no se cuantas líneas serán. Necesito la etiqueta de título para mostrar todas las líneas de texto. También necesito que las otras dos etiquetas y la pequeña imagen se establezcan justo debajo del título, sin importar lo alto que sea. También he establecido restricciones de espaciado vertical entre las etiquetas y la imagen pequeña como una restricción de espaciado superior entre la etiqueta de título y su vista superior y una restricción de espaciado inferior entre la imagen pequeña y su vista superior. El UIView blanco no tiene restricción de altura, por lo que debe estirarse verticalmente para contener sus subviews. He establecido el número de líneas para la etiqueta de título a 0.

¿Cómo puedo cambiar el tamaño de la etiqueta de título para que se ajuste al número de líneas requerido por la cadena? Mi entendimiento es que no puedo usar métodos setFrame porque estoy usando Auto Layout. Y yo tengo que usar Auto Layout porque necesito que esas otras vistas permanezcan debajo de la etiqueta de título (de ahí las restricciones).

¿Cómo puedo hacer que esto suceda?

Author: James Harpe, 2012-10-09

8 answers

Use -setPreferredMaxLayoutWidth en el UILabel y el diseño automático debe manejar el resto.

[label setPreferredMaxLayoutWidth:200.0];

Ver la documentación de UILabel.

ACTUALIZACIÓN:

Solo necesita establecer la restricción de altura en storyboard a Mayor o igual a", no es necesario Establecerpreferredmaxlayoutwidth.

 244
Author: mwhuss,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-12-30 08:32:32

Expanda su etiqueta establezca el número de líneas a 0 y también, lo que es más importante, para el diseño automático establezca la altura a >= x. El diseño automático hará el resto. También puede contener sus otros elementos basados en el elemento anterior para posicionar correctamente entonces.

diseño automático

 209
Author: Charlie Wu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-07-26 11:06:58

Fuente: http://www.objc.io/issue-3/advanced-auto-layout-toolbox.html

Tamaño del Contenido Intrínseco del Texto Multilínea

El tamaño de contenido intrínseco de UILabel y NSTextField es ambiguo para texto multilínea. La altura del texto depende del ancho de las líneas, que aún no se ha determinado al resolver las restricciones. Para resolver este problema, ambas clases tienen una nueva propiedad llamada preferredMaxLayoutWidth, que especifica la línea máxima ancho para calcular el tamaño del contenido intrínseco.

Dado que generalmente no conocemos este valor de antemano, necesitamos tomar un enfoque de dos pasos para hacerlo bien. Primero dejamos que el Diseño automático haga su trabajo, y luego usamos el marco resultante en el pase de diseño para actualizar el ancho máximo preferido y volver a activar el diseño.

- (void)layoutSubviews
{
    [super layoutSubviews];
    myLabel.preferredMaxLayoutWidth = myLabel.frame.size.width;
    [super layoutSubviews];
}

La primera llamada a [super layoutSubviews] es necesaria para que la etiqueta tenga su frame establecido, mientras que la segunda llamada es necesaria para actualizar el layout después del cambio. Si omitimos la segunda llamada obtenemos un error NSInternalInconsistencyException, porque hemos realizado cambios en el pase de layout que requieren actualizar las restricciones, pero no activamos layout de nuevo.

También podemos hacer esto en una subclase label:

@implementation MyLabel
- (void)layoutSubviews
{
    self.preferredMaxLayoutWidth = self.frame.size.width;
    [super layoutSubviews];
}
@end

En este caso, no necesitamos llamar primero a [super layoutSubviews], porque cuando se llama a layoutSubviews, ya tenemos un marco en la etiqueta misma.

Para hacer este ajuste desde el controlador de vista nivel, nos enganchamos en viewDidLayoutSubviews. En este punto, los fotogramas del primer pase de Diseño automático ya están configurados y podemos usarlos para establecer el ancho máximo preferido.

- (void)viewDidLayoutSubviews
{
    [super viewDidLayoutSubviews];
    myLabel.preferredMaxLayoutWidth = myLabel.frame.size.width;
    [self.view layoutIfNeeded];
}

Por último, asegúrate de no tener una restricción de altura explícita en la etiqueta que tenga una prioridad más alta que la prioridad de resistencia a la compresión de contenido de la etiqueta. De lo contrario, triunfará sobre la altura calculada del contenido. Asegúrese de comprobar todas las restricciones que pueden afectar a la etiqueta altura.

 44
Author: Anton Matosov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-03-21 07:30:13

Solo estaba luchando con este escenario exacto, pero con bastantes vistas más que necesitaban cambiar el tamaño y moverse hacia abajo según fuera necesario. Me estaba volviendo loco, pero finalmente lo entendí.

Aquí está la clave: a Interface Builder le gusta agregar restricciones adicionales a medida que agrega y mueve vistas y es posible que no lo note. En mi caso, tenía una vista a mitad de camino hacia abajo que tenía una restricción adicional que especificaba el tamaño entre ella y su supervisión, básicamente fijándola a ese punto. Eso significaba que nada por encima de él podría cambiar el tamaño más grande porque iría en contra de esa restricción.

Una manera fácil de saber si este es el caso es tratando de cambiar el tamaño de la etiqueta manualmente. ¿IB te deja crecer? Si lo hace, ¿las etiquetas a continuación se mueven como esperas? Asegúrese de tener ambos marcados antes de cambiar el tamaño para ver cómo sus restricciones moverán sus vistas:

Menú IB

Si la vista está atascada, siga las vistas que están debajo de ella y asegúrese de que una de ellas no tenga un espacio superior a superview restricción. A continuación, solo asegúrese de que su número de líneas opción para la etiqueta se establece en 0 y debe hacerse cargo del resto.

 16
Author: Cory Imdieke,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-10-18 21:03:07

Creo que necesitas lo siguiente:

  • Una restricción superior
  • Una restricción inicial (por ejemplo, lado izquierdo)
  • Una restricción final (por ejemplo, lado derecho)
  • Establezca la prioridad de abrazo de contenido, horizontal a baja, por lo que llenará el espacio dado si el texto es corto.
  • Establezca la resistencia a la compresión de contenido, horizontal a baja, por lo que se envolverá en lugar de tratar de hacerse más ancho.
  • Establezca el número de líneas en 0.
  • Establezca el modo de salto de línea en ajuste de línea.
 4
Author: Chris,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-04-11 01:01:03

Ninguna de las diferentes soluciones encontradas en los muchos temas sobre el tema funcionó perfectamente para mi caso (x etiquetas multilínea dinámicas en celdas de vista de tabla dinámica) .

Encontré una manera de hacerlo :

Después de haber establecido las restricciones en su etiqueta y establecer su propiedad multilínea en 0, haga una subclase de UILabel; llamé a la mía AutoLayoutLabel:

@implementation AutoLayoutLabel

- (void)layoutSubviews{
    [self setNeedsUpdateConstraints];
    [super layoutSubviews];
    self.preferredMaxLayoutWidth = CGRectGetWidth(self.bounds);
}

@end
 0
Author: Tanguy G.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-09-02 16:34:10

Tengo una UITableViewCell que tiene una etiqueta de ajuste de texto. Trabajé el ajuste de texto de la siguiente manera.

1) Establezca las restricciones UILabel de la siguiente manera.

introduzca la descripción de la imagen aquí

2) Conjunto no. de líneas a 0.

3) Se agregó restricción de altura de UILabel a UITableViewCell.

@IBOutlet weak var priorityLabelWidth: NSLayoutConstraint!

4) En UITableViewCell:

priorityLabel.sizeToFit()
priorityLabelWidth.constant = priorityLabel.intrinsicContentSize().width+5
 0
Author: A.G,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-07-28 06:33:07

Una forma de hacer esto... A medida que aumenta la longitud del texto, intente cambiar (disminuir) el tamaño de fuente del texto de la etiqueta usando

Label.adjustsFontSizeToFitWidth = YES;
 -8
Author: user1662392,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-10-15 13:21:58