UILabel: ¿etiqueta de tamaño automático para adaptarse al texto?

144

¿Es posible redimensionar automáticamente el cuadro / límites de UILabel para que se ajuste al texto contenido? (No me importa si termina más grande que la pantalla)

Entonces, si un usuario ingresa "hola" o "mi nombre es muy largo, quiero que quepa en este cuadro", ¿nunca se trunca y la etiqueta se 'amplía' en consecuencia?

wayneh
fuente
Alguien, por favor, ayúdenme a proporcionar códigos rápidos ...
Angel F Syrus

Respuestas:

98

Por favor revisa mi esencia donde he hecho una categoría para UILabelalgo muy similar, mi categoría permite UILabelestirar su altura para mostrar todo el contenido: https://gist.github.com/1005520

O echa un vistazo a esta publicación: https://stackoverflow.com/a/7242981/662605

Esto estiraría la altura, pero puede cambiarla fácilmente para trabajar de otra manera y estirar el ancho con algo como esto, que creo que es lo que quiere hacer:

@implementation UILabel (dynamicSizeMeWidth)

- (void)resizeToStretch{
    float width = [self expectedWidth];
    CGRect newFrame = [self frame];
    newFrame.size.width = width;
    [self setFrame:newFrame];
}

- (float)expectedWidth{
    [self setNumberOfLines:1];

    CGSize maximumLabelSize = CGSizeMake(CGRectGetWidth(self.bounds), CGFLOAT_MAX);

    CGSize expectedLabelSize = [[self text] sizeWithFont:[self font] 
                                            constrainedToSize:maximumLabelSize
                                            lineBreakMode:[self lineBreakMode]]; 
    return expectedLabelSize.width;
}

@end

Puede usar el sizeToFitmétodo disponible de la UIViewclase de manera más simple , pero establezca el número de líneas en 1 para que sea seguro.


actualización de iOS 6

Si está utilizando AutoLayout, entonces tiene una solución integrada. Al establecer el número de líneas en 0, el marco cambiará el tamaño de su etiqueta de manera apropiada (agregando más altura) para que se ajuste a su texto.


actualización de iOS 8

sizeWithFont:está en desuso, así que use sizeWithAttributes:en su lugar:

- (float)expectedWidth{
    [self setNumberOfLines:1];

    CGSize expectedLabelSize = [[self text] sizeWithAttributes:@{NSFontAttributeName:self.font}];

    return expectedLabelSize.width;
}
Daniel
fuente
8
Usando el método iOS 6 AutoLayout, terminé con una restricción de altura en mi etiqueta de la que no podía deshacerme. Establecer la relación de la restricción de altura en 'Mayor o igual que' permitió que la altura creciera.
Michael Luton
2
sizeWithFont: restrictinedToSize: lineBreakMode: método depricated en ios 7
Karan Alangat
1
UILabel no cambia su tamaño cuando el texto es menor / mayor. Estoy usando el diseño automático. Intenté hacer UILabel pero se crean cada vez que se inicializa cellForRowAtIndex. Intenté muchas cosas. Nada funciona para mi. El fondo de uilabel toma el mismo ancho. Ayuda !!!
coreDeviOS
@ Daniel Establecí el número de líneas = 0, pero no funciona. He establecido las restricciones de centro horizontal y vertical. Una cosa adicional que he hecho es hacer una subclase de UILABEL y usarlo para esa etiqueta
Jasmeet
Con Autolayout la solución más simple para: (1) Establecer líneas en 0, (2) Establecer la restricción de ancho en "Mayor o igual que" con la constante 0, (3) Establecer la restricción de altura en "Mayor o igual que" con la constante 0, ( 4) Alinee como lo haría normalmente, por ejemplo al centrar horizontal y verticalmente.
Erik van der Neut
76

El uso [label sizeToFit];logrará el mismo resultado de la categoría Daniels.

Aunque recomiendo usar autolayout y dejar que la etiqueta se redimensione según las restricciones.

Guilherme Torres Castro
fuente
3
Al usar swift, tuve que ejecutar esto en el hilo principal usando dispatch_async (dispatch_get_main_queue (), {});
Zeezer
@Zeezer, ¿sabes por qué?
FurloSK
13
@FurloSK Cualquier cambio en la interfaz de usuario debe hacerse en el hilo principal.
Guilherme Torres Castro
32

Si queremos que UILabelse reduzca y expanda según el tamaño del texto, entonces el guión gráfico con autolayout es la mejor opción. A continuación se detallan los pasos para lograrlo.

Pasos

  1. Ponga UILabel en el controlador de vista y colóquelo donde desee. También puesto 0por numberOfLinespropiedad de UILabel.

  2. Déle la restricción de pin de espacio superior, inicial y final.

ingrese la descripción de la imagen aquí

  1. Ahora dará advertencia, haga clic en la flecha amarilla.

ingrese la descripción de la imagen aquí

  1. Haga clic en Update Framey haga clic en Fix Misplacement. Ahora, este UILabel se reducirá si el texto es menor y se expandirá si el texto es mayor.
Yogesh Suthar
fuente
1
No he probado la localización, pero también debería funcionar para eso.
Yogesh Suthar
2
No pude hacer que esto funcione con un proyecto existente hasta que desactivé la casilla de verificación "Ancho preferido" "Explícito", luego todo funcionó bien.
zorro2b
25

Esto no es tan complicado como lo hacen algunas de las otras respuestas.

ingrese la descripción de la imagen aquí

Pin los bordes izquierdo y superior

Simplemente use el diseño automático para agregar restricciones para fijar los lados izquierdo y superior de la etiqueta.

ingrese la descripción de la imagen aquí

Después de eso, se redimensionará automáticamente.

Notas

  • No agregue restricciones para el ancho y la altura. Las etiquetas tienen un tamaño intrínseco en función de su contenido de texto.
  • Gracias a esta respuesta por ayuda con esto.
  • No es necesario configurarlo sizeToFitcuando se usa el diseño automático. Mi código completo para el proyecto de ejemplo está aquí:

    import UIKit
    class ViewController: UIViewController {
    
        @IBOutlet weak var myLabel: UILabel!
    
        @IBAction func changeTextButtonTapped(sender: UIButton) {
            myLabel.text = "my name is really long i want it to fit in this box"
        }
    }
  • Si desea que su etiqueta se ajuste a la línea, establezca el número de líneas en 0 en IB y agregue el myLabel.preferredMaxLayoutWidth = 150 // or whatevercódigo. (También fijé mi botón en la parte inferior de la etiqueta para que se moviera hacia abajo cuando aumentara la altura de la etiqueta).

ingrese la descripción de la imagen aquí

  • Si está buscando etiquetas de tamaño dinámico dentro de a UITableViewCell, consulte esta respuesta .

ingrese la descripción de la imagen aquí

Suragch
fuente
Hola, obtuve la etiqueta redimensionada pero no entiendo cómo cambiar el tamaño de la altura de la celda. ¿Me puede decir cómo cambiar el tamaño de la altura de la celda?
Vivek
@Vivek, siempre que no tenga ninguna restricción establecida en la altura, debe cambiar su tamaño automáticamente.
Suragch
Sí, pero cómo es posible cuando uso una celda personalizada y pongo 2 etiquetas en su celda.
Vivek
@Vivek, lo siento, leí mal tu pregunta. ¿Ya obtuviste una etiqueta para trabajar con esta respuesta ?
Suragch
9

Use [label sizeToFit];para ajustar el texto en UILabel

Gaurav Gilani
fuente
5

Creé algunos métodos basados ​​en la respuesta de Daniel anterior.

-(CGFloat)heightForLabel:(UILabel *)label withText:(NSString *)text
{
    CGSize maximumLabelSize     = CGSizeMake(290, FLT_MAX);

    CGSize expectedLabelSize    = [text sizeWithFont:label.font
                                constrainedToSize:maximumLabelSize
                                    lineBreakMode:label.lineBreakMode];

    return expectedLabelSize.height;
}

-(void)resizeHeightToFitForLabel:(UILabel *)label
{
    CGRect newFrame         = label.frame;
    newFrame.size.height    = [self heightForLabel:label withText:label.text];
    label.frame             = newFrame;
}

-(void)resizeHeightToFitForLabel:(UILabel *)label withText:(NSString *)text
{
    label.text              = text;
    [self resizeHeightToFitForLabel:label];
}
Doug Baker
fuente
5

Esto es lo que encuentro que funciona para mi situación:

1) La altura de UILabel tiene una restricción> = 0 usando autolayout. El ancho es fijo. 2) Asigne el texto en el UILabel, que ya tiene una vista general en ese punto (no estoy seguro de lo importante que es). 3) Luego, haz:

    label.sizeToFit()
    label.layoutIfNeeded()

La altura de la etiqueta ahora está configurada adecuadamente.

Chris Prince
fuente
3
@implementation UILabel (UILabel_Auto)

- (void)adjustHeight {

    if (self.text == nil) {
        self.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y, self.bounds.size.width, 0);
        return;
    }

    CGSize aSize = self.bounds.size;
    CGSize tmpSize = CGRectInfinite.size;
    tmpSize.width = aSize.width;

    tmpSize = [self.text sizeWithFont:self.font constrainedToSize:tmpSize];

    self.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y, aSize.width, tmpSize.height);
}

@end

Este es el método de categoría. Primero debe configurar el texto, que llamar a este método para ajustar la altura de UILabel.

Kaijay Lu
fuente
2

Puede cambiar el tamaño de su etiqueta de acuerdo con el texto y otros controles relacionados de dos maneras:

  1. Para iOS 7.0 y superior

    CGSize labelTextSize = [labelText boundingRectWithSize:CGSizeMake(labelsWidth, MAXFLOAT)
                                              options:NSStringDrawingUsesLineFragmentOrigin
                                           attributes:@{
                                                        NSFontAttributeName : labelFont
                                                        }
                                              context:nil].size;

antes de iOS 7.0, esto podría usarse para calcular el tamaño de la etiqueta

CGSize labelTextSize = [label.text sizeWithFont:label.font 
                            constrainedToSize:CGSizeMake(label.frame.size.width, MAXFLOAT)  
                                lineBreakMode:NSLineBreakByWordWrapping];

// replantea otros controles basados ​​en labelTextHeight

CGFloat labelTextHeight = labelTextSize.height;
  1. Si no desea calcular el tamaño del texto de la etiqueta, puede usar -sizeToFit en la instancia de UILabel como-

    [label setNumberOfLines:0]; // for multiline label
    [label setText:@"label text to set"];
    [label sizeToFit];// call this to fit size of the label according to text

// después de esto, puede obtener el marco de la etiqueta para replantear otros controles relacionados

vijeesh
fuente
2
  1. Agregue restricciones faltantes en el guión gráfico.
  2. Seleccione UILabel en el guión gráfico y establezca los atributos "Línea" en 0.
  3. Ref Outlet UILabel a Controller.h con id: etiqueta
  4. Controller.m y agregue [label sizeToFit];viewDidLoad
usuario2941395
fuente
1

Tuve un gran problema con el diseño automático. Tenemos dos contenedores dentro de la celda de la mesa. El segundo contenedor cambia de tamaño según la descripción del artículo (0 - 1000 caracteres), y la fila debe redimensionarse en función de ellos.

El ingrediente que faltaba era la restricción inferior para la descripción.

He cambiado la restricción inferior del elemento dinámico de = 0 a > = 0 .

Bojan Tadic
fuente
Esto me salvó la vida. Si está intentando seguir: github.com/honghaoz/… esta es la respuesta correcta.
Justin Fyles
0

¡Se adapta siempre! :)

    name.text = @"Hi this the text I want to fit to"
    UIFont * font = 14.0f;
    CGSize size = [name.text sizeWithAttributes:@{NSFontAttributeName: font}];
    nameOfAssessment.frame = CGRectMake(400, 0, size.width, 44);
    nameOfAssessment.font = [UIFont systemFontOfSize:font];
HannahCarney
fuente
0

puede mostrar una salida de línea y luego establecer la propiedad Línea = 0 y mostrar múltiples salidas de línea y luego establecer la propiedad Línea = 1 y más

[self.yourLableName sizeToFit];
Dixit Akabari
fuente
-1

También existe este enfoque:

[self.myLabel changeTextWithAutoHeight:self.myStringToAssignToLabel width:180.0f];
Dave Cole
fuente
No fui yo quien rechazó esta respuesta, pero solo quería señalar que no puedo ver un changeTextWithAutoHeight:width:método UILabel. ¿Podría proporcionar un enlace a dónde se puede encontrar este método en la documentación de UIKit?
Adil Hussain