UILabel sizeToFit no funciona con autolayout ios6

¿Cómo se supone que debo configurar mediante progtwigción (y en qué método) una UILabel cuya altura depende de su text? He intentado configurarlo usando una combinación de Storyboard y código, pero fue en vano. Todos recomiendan sizeToFit al configurar lineBreakMode y numberOfLines . Sin embargo, no importa si pongo ese código en viewDidLoad: viewDidAppear: o viewDidLayoutSubviews no puedo hacerlo funcionar. O hago que el cuadro sea demasiado pequeño para el text largo y no crece, o lo hago demasiado grande y no se encoge.

Tenga en count que, en la mayoría de los casos, la solución de Matt funciona como se esperaba. Pero si no te funciona, por favor, lee más.

Para que la label cambie automáticamente el tamaño de la altura, debe hacer lo siguiente:

  1. Establecer restricciones de layout para la label
  2. Establezca la restricción de altura con baja prioridad. Debería ser menor que ContentCompressionResistancePriority
  3. Establecer numberOfLines = 0
  4. Establezca ContentHuggingPriority más alto que la prioridad de altura de la label.
  5. Establezca prefernetworkingMaxLayoutWidth para la label. Ese valor es usado por la label para calcular su altura

Por ejemplo:

 self.descriptionLabel = [[UILabel alloc] init]; self.descriptionLabel.numberOfLines = 0; self.descriptionLabel.lineBreakMode = NSLineBreakByWordWrapping; self.descriptionLabel.prefernetworkingMaxLayoutWidth = 200; [self.descriptionLabel setContentHuggingPriority:UILayoutPriorityRequinetworking forAxis:UILayoutConstraintAxisVertical]; [self.descriptionLabel setContentCompressionResistancePriority:UILayoutPriorityRequinetworking forAxis:UILayoutConstraintAxisVertical]; [self.descriptionLabel setTranslatesAutoresizingMaskIntoConstraints:NO]; [self addSubview:self.descriptionLabel]; NSArray* constrs = [NSLayoutConstraint constraintsWithVisualFormat:@"|-8-[descriptionLabel_]-8-|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(descriptionLabel_)]; [self addConstraints:constrs]; [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-8-[descriptionLabel_]" options:0 metrics:nil views:NSDictionaryOfVariableBindings(descriptionLabel_)]]; [self.descriptionLabel addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[descriptionLabel_(220@300)]" options:0 metrics:nil views:NSDictionaryOfVariableBindings(descriptionLabel_)]]; 

Uso de Interface Builder

  1. Configura cuatro restricciones. La restricción de altura es obligatoria. introduzca la descripción de la imagen aquí

  2. Luego vaya al inspector de attributes de la label y establezca el número de líneas en 0. introduzca la descripción de la imagen aquí

  3. Vaya al inspector de tamaño de la label y aumente Vertical ContentHuggingPriority y vertical ContentCompressionResistancePriority.
    introduzca la descripción de la imagen aquí

  4. Seleccione y edite la restricción de altura.
    introduzca la descripción de la imagen aquí

  5. Y disminuya la prioridad de restricción de altura.
    introduzca la descripción de la imagen aquí

Disfrutar. 🙂

En iOS 6, si utiliza la reproducción automática, si los lados (o el ancho) y la parte superior de un UILabel están fijados, crecerá y se achicará verticalmente para adaptarse a su contenido, sin código alguno y sin problemas con su resistencia a la compression o lo que sea. Es muy simple

En casos más complejos, simplemente establezca PreferidoMaxLayoutWidth de la label.

De cualquier manera, lo correcto ocurre automáticamente.

A pesar de que la pregunta establece mediante progtwigción, habiendo encontrado el mismo problema y prefiriendo trabajar en Interface Builder, pensé que podría ser útil agregar las respuestas existentes con una solución de Interface Builder.

Lo primero es olvidar sizeToFit . El layout automático se encargará de esto en su nombre en function del tamaño de contenido intrínseco.

El problema, por lo tanto, es cómo get una label para su contenido con Auto Layout. Específicamente, porque la pregunta lo menciona: altura. Tenga en count que los mismos principios se aplican al ancho.

Entonces, comencemos con un ejemplo UILabel que tiene una altura establecida a 41px alto:

introduzca la descripción de la imagen aquí

Como puede ver en la captura de pantalla de arriba, "This is my text" tiene relleno arriba y abajo. Eso es relleno entre la altura de UILabel y su contenido, el text.

Si ejecutamos la aplicación en el simulador, por supuesto, vemos lo mismo:

introduzca la descripción de la imagen aquí

Ahora, selectmos UILabel en Interface Builder, y eche un vistazo a las configuraciones pnetworkingeterminadas en el inspector de Tamaño:

introduzca la descripción de la imagen aquí

Tenga en count la restricción resaltada anterior. Esa es la Prioridad de aarm de contenido . Como lo describe Erica Sadun en el excelente iOS Auto Layout Demystified , esto es:

la forma en que una vista prefiere evitar el relleno adicional alnetworkingedor del contenido central

Para nosotros, con la UILabel, el contenido principal es el text.

Aquí llegamos al corazón de este escenario básico. Hemos otorgado a nuestra label de text dos restricciones. Entran en conflicto Uno dice "la altura debe ser igual a 41 píxeles de alto" . El otro dice "abraza la vista a su contenido para que no tengamos más relleno" . En nuestro caso, abraza la vista a su text para que no tengamos relleno adicional.

Ahora, con Auto Layout, con dos instrucciones diferentes que dicen hacer cosas diferentes, el time de ejecución tiene que elegir uno u otro. No puede hacer ambas cosas. El UILabel no puede tener 41 píxeles de alto y no tiene relleno.

La forma en que esto se resuelve es mediante la especificación de prioridad. Una instrucción debe tener una mayor prioridad que la otra. Si ambas instrucciones dicen cosas diferentes y tienen la misma prioridad, se producirá una exception.

Así que vamos a intentarlo. Mi restricción de altura tiene una prioridad de 1000 , que es requerida . La altura de aarm de contenido es 250 , que es débil . ¿Qué sucede si networkingucimos la prioridad de restricción de altura a 249 ?

introduzca la descripción de la imagen aquí

Ahora podemos ver el comienzo mágico de suceder. Intentemos en el sim:

introduzca la descripción de la imagen aquí

¡Increíble! El aarm del contenido logrado. Solo porque la prioridad de altura 249 es menor que la prioridad de aarm de contenido 250 . Básicamente, estoy diciendo que "la altura que especifique aquí es less importante que lo que he especificado para el aarm de contenido" . Entonces, el contenido que abraza gana.

En pocas palabras, conseguir que la label se ajuste al text puede ser tan simple como especificar la restricción de altura o ancho, y corregir la configuration de esa prioridad en asociación con la restricción de prioridad de aarm de contenido de ese eje.

¡Saldrá haciendo el equivalente de ancho como un ejercicio para el lector!

Notado en IOS7, sizeToFit tampoco funcionaba, tal vez la solución pueda ayudarlo también

 [textView sizeToFit]; [textView layoutIfNeeded]; 

Otra opción para garantizar que la label PrefernetworkingMaxLayoutWidth se mantenga sincronizada con el ancho de la label:

 #import "MyLabel.h" @implementation MyLabel -(void)setBounds:(CGRect)bounds { [super setBounds:bounds]; // This appears to be needed for iOS 6 which doesn't seem to keep // label prefernetworkingMaxLayoutWidth in sync with its width, which // means the label won't grow vertically to encompass its text if // the label's width constraint changes. self.prefernetworkingMaxLayoutWidth = self.bounds.size.width; } @end 

Siento que debo contribuir, ya que me tomó un time encontrar la solución adecuada:

  • El objective es dejar que Auto Layout haga su trabajo sin siquiera llamar a sizeToFit (), haremos esto especificando las restricciones correctas:
  • Especifique restricciones de espacio superior, inferior e inicial / posterior en su UILabel
  • Establezca la propiedad de número de líneas en 0
  • Incrementa la prioridad de aarm de contenido a 1000
  • Baje la prioridad de resistencia de compression de contenido a 500
  • En la restricción del contenedor inferior, networkinguzca la prioridad a 500

Básicamente, lo que sucede es que le dices a tu UILabel que, aunque tiene una restricción de altura fija, puede hacer que la restricción se networkinguzca para abarcar el contenido (si tienes una sola línea, por ejemplo), pero no puede Rompe la restricción para que sea más grande.

En mi caso, estaba creando una subclass UIView que contenía una UILabel (de longitud desconocida). En iOS7, el código era sencillo: establezca las restricciones, no se preocupe por el aarm de contenido o la resistencia a la compression, y todo funcionó como se esperaba.

Pero en iOS6, la UILabel siempre estaba recortada en una sola línea. Ninguna de las respuestas anteriores funcionó para mí. Se ignoraron las configuraciones de resistencia de compression y compression de contenido. La única solución que evitaba el clipping era include un MaxMayoutWidth preferido en la label. Pero no sabía a qué establecer el ancho preferido, ya que el tamaño de su vista principal era desconocido (de hecho, estaría definido por los contenidos).

Finalmente encontré la solución aquí . Como trabajaba en una vista personalizada, solo podía agregar el siguiente método para establecer el ancho de layout preferido una vez que las restricciones se habían calculado una vez y luego volver a calcularlas:

 - (void)layoutSubviews { // Autolayout hack requinetworking for iOS6 [super layoutSubviews]; self.bodyLabel.prefernetworkingMaxLayoutWidth = self.bodyLabel.frame.size.width; [super layoutSubviews]; } 

He resuelto con xCode6 poniendo "Ancho preferido" en Automático y pincho la parte superior de la label, el encabezado y el final introduzca la descripción de la imagen aquí

 UIFont *customFont = myLabel.font; CGSize size = [trackerStr sizeWithFont:customFont constrainedToSize:myLabel.frame.size // the size here should be the maximum size you want give to the label lineBreakMode:UILineBreakModeWordWrap]; float numberOfLines = size.height / customFont.lineHeight; myLabel.numberOfLines = numberOfLines; myLabel.frame = CGRectMake(258, 18, 224, (numberOfLines * customFont.lineHeight)); 

También me encontré con este problema con una subclass UIView que contiene un UILabel como uno si sus elementos internos. Incluso con la reproducción automática y probando todas las soluciones recomendadas, la label simplemente no ajustaría su altura al text. En mi caso, solo quiero que la label sea una sola línea.

De todos modos, lo que funcionó para mí fue agregar una restricción de altura requerida para el UILabel y configurarlo manualmente a la altura correcta cuando se llama intrinsicContentSize. Si no tiene la UILabel contenida en otra UIView, puede intentar subclasificar UILabel y proporcionar una implementación similar estableciendo primero la restricción de altura y luego regresando
[super instrinsicContentSize]; en lugar de [self.containerview intrinsiceContentSize]; como lo hago a continuación, que es específico de mi subclass UIView.

 - (CGSize)intrinsicContentSize { CGRect expectedTextBounds = [self.titleLabel textRectForBounds:self.titleLabel.bounds limitedToNumberOfLines:1]; self.titleLabelHeightConstraint.constant = expectedTextBounds.size.height; return [self.containerView intrinsicContentSize]; } 

Funciona perfectamente ahora en iOS 7 y iOS 8.

UILabel progtwigción y en mi caso eso fue suficiente:

 label.translatesAutoresizingMaskIntoConstraints = false label.setContentCompressionResistancePriority(UILayoutPriorityRequinetworking, forAxis: .Vertical) label.numberOfLines = 0 

Una solución que funcionó para mí; Si su UILabel tiene un ancho fijo, cambie la restricción de constant = a constant <= en su file de interfaz

introduzca la descripción de la imagen aquí

En mi caso, al usar las tags en una UITableViewCell, la label en cambiaría de tamaño, pero la altura sobrepasaría la altura de la celda de la tabla. Esto es lo que funcionó para mí. Lo hice de acuerdo con Max MacLeod, y luego me aseguré de que la altura de la celda estuviera establecida en UITableViewAutomaticDimension.

Puede agregar esto en su init o awakeFromNib,

 self.tableView.rowHeight = UITableViewAutomaticDimension. 

En el guión gráfico, select la celda, abra el inspector de Tamaño y asegúrese de que la altura de la fila esté configurada en "Pnetworkingeterminado" haciendo clic en la checkbox "Personalizada".

Existe un problema en 8.0 que también requiere que se establezca en el código.