Alinear verticalmente el texto hacia arriba dentro de una UILabel
tengo unUILabel
espacio para dos líneas de texto. A veces, cuando el texto es demasiado corto, este texto se muestra en el centro vertical de la etiqueta.
¿Cómo alineo verticalmente el texto para que esté siempre en la parte superior UILabel
?
No hay forma de establecer la alineación vertical en un archivo UILabel
, pero puedes obtener el mismo efecto cambiando el marco de la etiqueta. He hecho mis etiquetas de color naranja para que puedas ver claramente lo que está sucediendo.
Esta es la manera rápida y fácil de hacer esto:
[myLabel sizeToFit];
Si tiene una etiqueta con texto más largo que ocupará más de una línea, configúrela numberOfLines
en 0
(cero aquí significa un número ilimitado de líneas).
myLabel.numberOfLines = 0;
[myLabel sizeToFit];
Versión más larga
Haré mi etiqueta en código para que puedas ver lo que está pasando. También puedes configurar la mayor parte de esto en Interface Builder. Mi configuración es una aplicación basada en vistas con una imagen de fondo que hice en Photoshop para mostrar los márgenes (20 puntos). La etiqueta es de un atractivo color naranja para que puedas ver lo que sucede con las dimensiones.
- (void)viewDidLoad
{
[super viewDidLoad];
// 20 point top and left margin. Sized to leave 20 pt at right.
CGRect labelFrame = CGRectMake(20, 20, 280, 150);
UILabel *myLabel = [[UILabel alloc] initWithFrame:labelFrame];
[myLabel setBackgroundColor:[UIColor orangeColor]];
NSString *labelText = @"I am the very model of a modern Major-General, I've information vegetable, animal, and mineral";
[myLabel setText:labelText];
// Tell the label to use an unlimited number of lines
[myLabel setNumberOfLines:0];
[myLabel sizeToFit];
[self.view addSubview:myLabel];
}
Algunas limitaciones de uso sizeToFit
entran en juego con el texto alineado al centro o a la derecha. Esto es lo que sucede:
// myLabel.textAlignment = NSTextAlignmentRight;
myLabel.textAlignment = NSTextAlignmentCenter;
[myLabel setNumberOfLines:0];
[myLabel sizeToFit];
La etiqueta todavía tiene el tamaño de una esquina superior izquierda fija. Puede guardar el ancho de la etiqueta original en una variable y establecerlo después sizeToFit
, o darle un ancho fijo para contrarrestar estos problemas:
myLabel.textAlignment = NSTextAlignmentCenter;
[myLabel setNumberOfLines:0];
[myLabel sizeToFit];
CGRect myFrame = myLabel.frame;
// Resize the frame's width to 280 (320 - margins)
// width could also be myOriginalLabelFrame.size.width
myFrame = CGRectMake(myFrame.origin.x, myFrame.origin.y, 280, myFrame.size.height);
myLabel.frame = myFrame;
Tenga en cuenta que sizeToFit
respetará el ancho mínimo de su etiqueta inicial. Si comienza con una etiqueta de 100 de ancho y sizeToFit
la solicita, le devolverá una etiqueta (posiblemente muy alta) con 100 (o un poco menos) de ancho. Es posible que desee configurar su etiqueta al ancho mínimo que desee antes de cambiar el tamaño.
Algunas otras cosas a tener en cuenta:
Que lineBreakMode
se respete depende de cómo se establezca. NSLineBreakByTruncatingTail
(el valor predeterminado) se ignora después de sizeToFit
, al igual que los otros dos modos de truncamiento (principal y medio). NSLineBreakByClipping
también se ignora. NSLineBreakByCharWrapping
Funciona como de costumbre. El ancho del marco aún se reduce para ajustarse a la letra más a la derecha.
Mark Amery dio una solución para NIB y Storyboards usando Auto Layout en los comentarios:
Si su etiqueta está incluida en una plumilla o guión gráfico como una subvista de un
view
ViewController que usa diseño automático, entonces poner susizeToFit
llamadaviewDidLoad
no funcionará, porque el diseño automático dimensiona y posiciona las subvistas después de queviewDidLoad
se llama e inmediatamente deshará los efectos de susizeToFit
llamar. Sin embargo, llamarsizeToFit
desde dentroviewDidLayoutSubviews
funcionará .
Mi respuesta original (para la posteridad/referencia):
Esto utiliza el NSString
método sizeWithFont:constrainedToSize:lineBreakMode:
para calcular la altura del marco necesaria para ajustar una cadena, luego establece el origen y el ancho.
Cambie el tamaño del marco de la etiqueta usando el texto que desea insertar. De esa manera puedes acomodar cualquier número de líneas.
CGSize maximumSize = CGSizeMake(300, 9999);
NSString *dateString = @"The date today is January 1st, 1999";
UIFont *dateFont = [UIFont fontWithName:@"Helvetica" size:14];
CGSize dateStringSize = [dateString sizeWithFont:dateFont
constrainedToSize:maximumSize
lineBreakMode:self.dateLabel.lineBreakMode];
CGRect dateFrame = CGRectMake(10, 10, 300, dateStringSize.height);
self.dateLabel.frame = dateFrame;
Establecer el nuevo texto:
myLabel.text = @"Some Text"
Establezca el
maximum number
número de líneas en 0 (automático):myLabel.numberOfLines = 0
Establezca el marco de la etiqueta al tamaño máximo:
myLabel.frame = CGRectMake(20,20,200,800)
Llame
sizeToFit
para reducir el tamaño del marco para que el contenido quepa exactamente:[myLabel sizeToFit]
El marco de las etiquetas ahora es lo suficientemente alto y ancho para caber en el texto. La parte superior izquierda no debe modificarse. Probé esto solo con el texto alineado arriba a la izquierda. Para otras alineaciones, es posible que tengas que modificar el marco posteriormente.
Además, mi etiqueta tiene habilitado el ajuste de palabras.
En caso de que pueda ser de ayuda para alguien, tuve el mismo problema pero pude resolverlo simplemente cambiando de usar UILabel
a usar UITextView
. Aprecio que esto no sea para todos porque la funcionalidad es un poco diferente.
Si cambia a usar UITextView
, puede desactivar todas las propiedades de Vista de desplazamiento, así como Interacción del usuario habilitada... Esto lo obligará a actuar más como una etiqueta.