iphone - adaptive - iOS: UILabel multilínea en diseño automático
cocoa touch ios (8)
Tengo problemas para tratar de lograr un comportamiento de diseño muy básico con Diseño automático. Mi controlador de vista se ve así en IB:
La etiqueta superior es la etiqueta del título, no sé cuántas líneas será. Necesito la etiqueta del título para mostrar todas las líneas de texto. También necesito que las otras dos etiquetas y la imagen pequeña se coloquen justo debajo del título, por muy alto que sea. Establecí restricciones de espaciado vertical entre las etiquetas y la imagen pequeña, así como una restricción de espaciado superior entre la etiqueta de título y su supervista y una restricción de espaciado inferior entre la imagen pequeña y su supervista. La UIView blanca no tiene restricción de altura, por lo que debe extenderse verticalmente para contener sus subvistas. Establecí el número de líneas para la etiqueta del título en 0.
¿Cómo puedo hacer que la etiqueta del título cambie de tamaño para que se ajuste al número de líneas requeridas por la cadena? Según entiendo, no puedo usar los métodos de setFrame porque estoy usando el diseño automático. Y tengo que usar Diseño automático porque necesito que esas otras vistas permanezcan debajo de la etiqueta del título (de ahí las restricciones).
¿Cómo puedo hacer que esto suceda?
Creo que necesitas lo siguiente:
- Una restricción superior
- Una limitación principal (por ejemplo, el lado izquierdo)
- Una restricción final (por ejemplo, el lado derecho)
- Establezca la prioridad de abrazos de contenido, horizontal a baja, de modo que llene el espacio dado si el texto es corto.
- Establezca la resistencia a la compresión del contenido, de horizontal a baja, para que se ajuste en lugar de intentar ensancharse.
- Establezca el número de líneas a 0.
- Establezca el modo de salto de línea para ajustar la palabra.
Expande el número de líneas del conjunto de etiquetas a 0 y también más importante para la altura del conjunto de diseño automático a> = x. El diseño automático hará el resto. También puede contener sus otros elementos basados en el elemento anterior para colocarlos correctamente entonces.
Fuente: http://www.objc.io/issue-3/advanced-auto-layout-toolbox.html
Tamaño del contenido intrínseco del texto de líneas múltiples
El tamaño del contenido intrínseco de UILabel y NSTextField es ambiguo para el texto de varias líneas. 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 el ancho de línea máximo para calcular el tamaño de contenido intrínseco.
Dado que generalmente no conocemos este valor por adelantado, tenemos que tomar un enfoque de dos pasos para hacerlo bien. Primero permitimos que Auto Layout haga su trabajo, y luego usamos el marco resultante en el pase de diseño para actualizar el ancho máximo preferido y disparar el diseño nuevamente.
- (void)layoutSubviews
{
[super layoutSubviews];
myLabel.preferredMaxLayoutWidth = myLabel.frame.size.width;
[super layoutSubviews];
}
La primera llamada a [superdispositivoSubviews] es necesaria para que la etiqueta obtenga su marco establecido, mientras que la segunda llamada es necesaria para actualizar el diseño después del cambio. Si omitimos la segunda llamada, obtenemos un error NSInternalInconsistencyException, porque hemos realizado cambios en el pase de diseño que requieren la actualización de las restricciones, pero no activamos el diseño nuevamente.
También podemos hacer esto en una subclase de etiquetas:
@implementation MyLabel
- (void)layoutSubviews
{
self.preferredMaxLayoutWidth = self.frame.size.width;
[super layoutSubviews];
}
@end
En este caso, no es necesario que llamemos a [superdispositivoSubviews] primero, porque cuando se llama a layoutSubviews, ya tenemos un marco en la etiqueta.
Para realizar este ajuste desde el nivel del controlador de vista, enganchamos en viewDidLayoutSubviews. En este punto, los marcos 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úrese de no tener una restricción explícita de altura 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, prevalecerá la altura calculada del contenido. Asegúrese de verificar todas las restricciones que pueden afectar la altura de la etiqueta.
Ninguna de las diferentes soluciones encontradas en los muchos temas sobre el tema funcionó perfectamente para mi caso (x etiquetas dinámicas de líneas múltiples en celdas dinámicas de vista de tabla).
Encontré una manera de hacerlo:
Después de establecer las restricciones en su etiqueta y establecer su propiedad de línea múltiple en 0, cree una subclase de UILabel; Llamé a la mía AutoLayoutLabel:
@implementation AutoLayoutLabel
- (void)layoutSubviews{
[self setNeedsUpdateConstraints];
[super layoutSubviews];
self.preferredMaxLayoutWidth = CGRectGetWidth(self.bounds);
}
@end
Solo estaba peleando con este escenario exacto, pero con bastantes vistas más que necesitaban cambiar de tamaño y mover hacia abajo según fuera necesario. Me estaba volviendo loco, pero finalmente lo descubrí.
Aquí está la clave: Interface Builder le gusta agregar restricciones adicionales a medida que agrega y mueve vistas y puede que no lo note. En mi caso, tenía una vista a la mitad que tenía una restricción adicional que especificaba el tamaño entre ella y su supervista, básicamente fijándola en ese punto. Eso significaba que nada por encima de él podría cambiar de tamaño más grande porque iría en contra de esa restricción.
Una forma fácil de saber si este es el caso es tratando de cambiar el tamaño de la etiqueta de forma manual. ¿IB te permite crecer? Si es así, ¿las etiquetas a continuación se mueven como esperabas? Asegúrate de que hayas marcado estos dos elementos antes de cambiar el tamaño para ver cómo tus restricciones moverán tus vistas:
Si la vista está atascada, siga las vistas que se encuentran debajo y asegúrese de que una de ellas no tenga un espacio superior para supervisar la restricción. Luego solo asegúrate de que la opción de número de líneas para la etiqueta esté configurada en 0 y se encargue del resto.
Tengo una UITableViewCell que tiene una etiqueta de texto envolvente. Trabajé en el ajuste del texto de la siguiente manera.
1) Establezca las restricciones de UILabel de la siguiente manera.
2) Establecer no. de líneas a 0.
3) Se agregó la restricción de altura UILabel a UITableViewCell.
@IBOutlet weak var priorityLabelWidth: NSLayoutConstraint!
4) En UITableViewCell:
priorityLabel.sizeToFit()
priorityLabelWidth.constant = priorityLabel.intrinsicContentSize().width+5
Una forma de hacerlo ... 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;
Use -setPreferredMaxLayoutWidth
en el UILabel
y el UILabel
automático debería manejar el resto.
[label setPreferredMaxLayoutWidth:200.0];
Vea la documentación de UILabel .
ACTUALIZAR:
Solo necesita establecer la restricción de altura en el guión gráfico en Mayor o igual a ", no es necesario establecer PreferredMaxLayoutWidth.