Alinear verticalmente el texto hacia arriba dentro de un UILabel

Tengo un UILabel con 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 alinear verticalmente el texto para que siempre esté en la parte superior de UILabel ?

imagen que representa un UILabel con texto centrado verticalmente

No hay forma de establecer la alineación vertical en un UILabel , pero puede obtener el mismo efecto cambiando el marco de la etiqueta. He hecho que mis tags sean naranjas para que puedas ver claramente lo que está sucediendo.

Aquí está la manera rápida y fácil de hacer esto:

  [myLabel sizeToFit]; 

sizeToFit para exprimir una etiqueta


Si tiene una etiqueta con texto más largo que formará más de una línea, establezca numberOfLines en 0 (cero aquí significa un número ilimitado de líneas).

  myLabel.numberOfLines = 0; [myLabel sizeToFit]; 

Texto de etiqueta más largo con sizeToFit


Versión más larga

Haré mi etiqueta en código para que pueda ver lo que está pasando. Puede configurar la mayor parte de esto en Interface Builder también. Mi configuración es una aplicación basada en la vista con una imagen de fondo que hice en Photoshop para mostrar los márgenes (20 puntos). La etiqueta es de un color naranja atractivo para que pueda ver lo que está sucediendo 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 usar 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]; 

enter image description here

La etiqueta todavía se clasifica con una esquina superior izquierda. Puede guardar el ancho de la etiqueta original en una variable y configurarlo después de 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; 

alineación de etiquetas


Tenga en cuenta que sizeToFit respetará el ancho mínimo de su etiqueta inicial. Si comienza con una etiqueta de 100 de ancho y llama a sizeToFit en ella, le devolverá una etiqueta (posiblemente muy alta) con un ancho de 100 (o un poco menor). Es posible que desee establecer su etiqueta con el ancho mínimo que desee antes de cambiar el tamaño.

Corrija la alineación de la etiqueta cambiando el ancho del marco

Algunas otras cosas a tener en cuenta:

Si se respeta lineBreakMode depende de cómo esté configurado. NSLineBreakByTruncatingTail (el predeterminado) se ignora después de sizeToFit , al igual que los otros dos modos de truncamiento (cabeza 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 de la derecha.


Mark Amery dio una solución para NIBs y Storyboards usando Auto Layout en los comentarios:

Si su etiqueta está incluida en un plumón o guión gráfico como una subvista de la view de un ViewController que usa el autolayout, entonces poner su llamada viewDidLoad en viewDidLoad no funcionará, porque el autolayout dimensiona y posiciona las subvistas después de viewDidLoad y lo deshará inmediatamente los efectos de su llamada sizeToFit . Sin embargo, llamar a sizeToFit desde viewDidLayoutSubviews funcionará.


Mi respuesta original (para posteridad / referencia):

Utiliza el método sizeWithFont:constrainedToSize:lineBreakMode: para calcular la altura del cuadro necesaria para caber en una cadena, luego establece el origen y el ancho.

Cambiar el tamaño del marco de la etiqueta con el texto que desea insertar. De esta forma puede acomodar cualquier cantidad 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; 
  1. Establecer el nuevo texto:

     myLabel.text = @"Some Text" 
  2. Establezca el maximum number de líneas en 0 (automático):

     myLabel.numberOfLines = 0 
  3. Establezca el marco de la etiqueta al tamaño máximo:

     myLabel.frame = CGRectMake(20,20,200,800) 
  4. Llame a sizeToFit para reducir el tamaño del marco para que el contenido se ajuste:

     [myLabel sizeToFit] 

El marco de tags ahora es alto y lo suficientemente ancho como para adaptarse a su texto. La parte superior izquierda no debe ser modificada. Lo he probado solo con el texto alineado arriba a la izquierda. Para otras alineaciones, puede que tenga que modificar el marco después.

Además, mi etiqueta tiene activado el ajuste de palabras.

Refiriéndose a la solución de extensión:

 for(int i=1; i< newLinesToPad; i++) self.text = [self.text stringByAppendingString:@"\n"]; 

debe ser reemplazado por

 for(int i=0; i 

Se necesita espacio adicional en cada nueva línea agregada, ya que el carro posterior de iPhone UILabels parece ser ignorado 🙁

De forma similar, alignBottom también debe actualizarse con @" \n@%" en lugar de "\n@%" (para la inicialización del ciclo debe reemplazarse por "for (int i = 0 ..." también).

La siguiente extensión funciona para mí:

 // -- file: UILabel+VerticalAlign.h #pragma mark VerticalAlign @interface UILabel (VerticalAlign) - (void)alignTop; - (void)alignBottom; @end // -- file: UILabel+VerticalAlign.m @implementation UILabel (VerticalAlign) - (void)alignTop { CGSize fontSize = [self.text sizeWithFont:self.font]; double finalHeight = fontSize.height * self.numberOfLines; double finalWidth = self.frame.size.width; //expected width of label CGSize theStringSize = [self.text sizeWithFont:self.font constrainedToSize:CGSizeMake(finalWidth, finalHeight) lineBreakMode:self.lineBreakMode]; int newLinesToPad = (finalHeight - theStringSize.height) / fontSize.height; for(int i=0; i 

Luego, llame a [yourLabel alignTop]; o [yourLabel alignBottom]; después de cada asignación de texto de su etiqueta.

En caso de que sea de alguna ayuda para alguien, tuve el mismo problema pero pude resolver el problema 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 la Vista de desplazamiento así como la Interacción del usuario habilitada … Esto lo forzará a actuar más como una etiqueta.

enter image description here

Sin despeinarse sin problemas

 @interface MFTopAlignedLabel : UILabel @end @implementation MFTopAlignedLabel - (void)drawTextInRect:(CGRect) rect { NSAttributedString *attributedText = [[NSAttributedString alloc] initWithString:self.text attributes:@{NSFontAttributeName:self.font}]; rect.size.height = [attributedText boundingRectWithSize:rect.size options:NSStringDrawingUsesLineFragmentOrigin context:nil].size.height; if (self.numberOfLines != 0) { rect.size.height = MIN(rect.size.height, self.numberOfLines * self.font.lineHeight); } [super drawTextInRect:rect]; } @end 

No muss, no Objective-c, sin complicaciones, pero Swift 3:

 class VerticalTopAlignLabel: UILabel { override func drawText(in rect:CGRect) { guard let labelText = text else { return super.drawText(in: rect) } let attributedText = NSAttributedString(string: labelText, attributes: [NSFontAttributeName: font]) var newRect = rect newRect.size.height = attributedText.boundingRect(with: rect.size, options: .usesLineFragmentOrigin, context: nil).size.height if numberOfLines != 0 { newRect.size.height = min(newRect.size.height, CGFloat(numberOfLines) * font.lineHeight) } super.drawText(in: newRect) } } 

Me gusta la respuesta anterior, pero no estaba del todo bien, o es fácil copiar el código, así que lo limpié un poco. Agregue esta extensión a su propio archivo .h y .m o simplemente péguelo justo arriba de la implementación que pretende usar:

 #pragma mark VerticalAlign @interface UILabel (VerticalAlign) - (void)alignTop; - (void)alignBottom; @end @implementation UILabel (VerticalAlign) - (void)alignTop { CGSize fontSize = [self.text sizeWithFont:self.font]; double finalHeight = fontSize.height * self.numberOfLines; double finalWidth = self.frame.size.width; //expected width of label CGSize theStringSize = [self.text sizeWithFont:self.font constrainedToSize:CGSizeMake(finalWidth, finalHeight) lineBreakMode:self.lineBreakMode]; int newLinesToPad = (finalHeight - theStringSize.height) / fontSize.height; for(int i=0; i< = newLinesToPad; i++) { self.text = [self.text stringByAppendingString:@" \n"]; } } - (void)alignBottom { CGSize fontSize = [self.text sizeWithFont:self.font]; double finalHeight = fontSize.height * self.numberOfLines; double finalWidth = self.frame.size.width; //expected width of label CGSize theStringSize = [self.text sizeWithFont:self.font constrainedToSize:CGSizeMake(finalWidth, finalHeight) lineBreakMode:self.lineBreakMode]; int newLinesToPad = (finalHeight - theStringSize.height) / fontSize.height; for(int i=0; i< newLinesToPad; i++) { self.text = [NSString stringWithFormat:@" \n%@",self.text]; } } @end 

Y luego para usar, coloque su texto en la etiqueta y luego llame al método apropiado para alinearlo:

 [myLabel alignTop]; 

o

 [myLabel alignBottom]; 

Una forma aún más rápida (y más sucia) de lograr esto es establecer el modo de corte de línea de UILabel en “Clip” y agregar una cantidad fija de líneas nuevas.

 myLabel.lineBreakMode = UILineBreakModeClip; myLabel.text = [displayString stringByAppendingString:"\n\n\n\n"]; 

Esta solución no funcionará para todos, en particular, si aún desea mostrar “…” al final de la cadena si supera el número de líneas que muestra, deberá usar una de los bits de código más largos, pero en muchos casos esto te dará lo que necesitas.

En lugar de UILabel puede usar UITextField que tiene una opción de alineación vertical:

 textField.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter; textField.userInteractionEnabled = NO; // Don't allow interaction 

He luchado con este durante mucho tiempo y quería compartir mi solución.

Esto le dará un UILabel que reescribirá automáticamente el texto a 0.5 escalas y centrará verticalmente el texto. Estas opciones también están disponibles en Storyboard / IB.

 [labelObject setMinimumScaleFactor:0.5]; [labelObject setBaselineAdjustment:UIBaselineAdjustmentAlignCenters]; 

Crea una nueva clase

LabelTopAlign

archivo .h

 #import  @interface KwLabelTopAlign : UILabel { } @end 

archivo .m

 #import "KwLabelTopAlign.h" @implementation KwLabelTopAlign - (void)drawTextInRect:(CGRect)rect { int lineHeight = [@"IglL" sizeWithFont:self.font constrainedToSize:CGSizeMake(rect.size.width, 9999.0f)].height; if(rect.size.height >= lineHeight) { int textHeight = [self.text sizeWithFont:self.font constrainedToSize:CGSizeMake(rect.size.width, rect.size.height)].height; int yMax = textHeight; if (self.numberOfLines > 0) { yMax = MIN(lineHeight*self.numberOfLines, yMax); } [super drawTextInRect:CGRectMake(rect.origin.x, rect.origin.y, rect.size.width, yMax)]; } } @end 

Editar

Aquí hay una implementación más simple que hace lo mismo:

 #import "KwLabelTopAlign.h" @implementation KwLabelTopAlign - (void)drawTextInRect:(CGRect)rect { CGFloat height = [self.text sizeWithFont:self.font constrainedToSize:rect.size lineBreakMode:self.lineBreakMode].height; if (self.numberOfLines != 0) { height = MIN(height, self.font.lineHeight * self.numberOfLines); } rect.size.height = MIN(rect.size.height, height); [super drawTextInRect:rect]; } @end 

enter image description here

En Interface Builder

  • Establezca UILabel al tamaño del texto más grande posible
  • Establecer Lines a ‘0’ en el Inspector de atributos

En tu código

  • Establecer el texto de la etiqueta
  • Llame a sizeToFit en su etiqueta

Fragmento de código:

 self.myLabel.text = @"Short Title"; [self.myLabel sizeToFit]; 

Crea una subclase de UILabel. Funciona de maravilla:

 // TopLeftLabel.h #import  @interface TopLeftLabel : UILabel { } @end // TopLeftLabel.m #import "TopLeftLabel.h" @implementation TopLeftLabel - (id)initWithFrame:(CGRect)frame { return [super initWithFrame:frame]; } - (CGRect)textRectForBounds:(CGRect)bounds limitedToNumberOfLines:(NSInteger)numberOfLines { CGRect textRect = [super textRectForBounds:bounds limitedToNumberOfLines:numberOfLines]; textRect.origin.y = bounds.origin.y; return textRect; } -(void)drawTextInRect:(CGRect)requestedRect { CGRect actualRect = [self textRectForBounds:requestedRect limitedToNumberOfLines:self.numberOfLines]; [super drawTextInRect:actualRect]; } @end 

Como se discutió aquí .

Para la interfaz de usuario adaptable (iOS8 o posterior), la alineación vertical de UILabel se configurará desde StoryBoard al cambiar las propiedades noOfLines = noOfLines y

Restricciones

  1. Ajuste de UILabel LefMargin, RightMargin y Restricciones de Margen Superior.

  2. Cambiar la Content Compression Resistance Priority For Vertical = 1000` De modo que Vertical> Horizontal.

Restricciones de UILabel

Editado:

 noOfLines=0 

y las siguientes limitaciones son suficientes para lograr los resultados deseados.

enter image description here

Escribí una función de utilidad para lograr este propósito. Puedes echar un vistazo:

 // ajusta la altura de una etiqueta de varias líneas para alinearla verticalmente con la parte superior
 + (void) alignLabelWithTop: (UILabel *) label {
   CGSize maxSize = CGSizeMake (label.frame.size.width, 999);
   label.adjustsFontSizeToFitWidth = NO;

   // obtener la altura real
   CGSize actualSize = [label.text sizeWithFont: label.font constrainedToSize: maxSize lineBreakMode: label.lineBreakMode];
   CGRect rect = label.frame;
   rect.size.height = actualSize.height;
   label.frame = rect;
 }

.¿Cómo utilizar? (Si lblHello es creado por el constructor de Interface, entonces omito algunos detalles de los atributos de UILabel)

 lblHello.text = @ "¡Hola mundo! ¡Hola mundo! ¡Hola mundo! ¡Hola mundo! ¡Hola mundo! ¡Hola mundo! ¡Hola mundo! ¡Hola mundo!";
 lblHello.numberOfLines = 5;
 [Utils alignLabelWithTop: lblHello];

También lo escribí en mi blog como un artículo: http://fstoke.me/blog/?p=2819

Me tomó un tiempo leer el código, así como el código en la página introducida, y encontré que todos intentan modificar el tamaño del marco de la etiqueta, de modo que la alineación vertical central predeterminada no aparezca.

Sin embargo, en algunos casos queremos que la etiqueta ocupe todos esos espacios, incluso si la etiqueta tiene tanto texto (por ejemplo, varias filas con la misma altura).

Aquí, utilicé una forma alternativa de resolverlo, simplemente rellenando las líneas nuevas hasta el final de la etiqueta (por favor, tenga en cuenta que en realidad heredé el UILabel , pero no es necesario):

 CGSize fontSize = [self.text sizeWithFont:self.font]; finalHeight = fontSize.height * self.numberOfLines; finalWidth = size.width; //expected width of label CGSize theStringSize = [self.text sizeWithFont:self.font constrainedToSize:CGSizeMake(finalWidth, finalHeight) lineBreakMode:self.lineBreakMode]; int newLinesToPad = (finalHeight - theStringSize.height) / fontSize.height; for(int i = 0; i < newLinesToPad; i++) { self.text = [self.text stringByAppendingString:@"\n "]; } 

Solución de guión gráfico: la forma más sencilla y sencilla es insertar Label en StackView y establecer el Axis de StackView en Horizontal , Alignment en la parte Top en el Attribute Inspector desde Storyboard.

enter image description here

Tomé las sugerencias aquí y creé una vista que puede envolver un UILabel y lo dimensionará y establecerá el número de líneas para que esté alineado en la parte superior. Simplemente ponga un UILabel como una subvista:

 @interface TopAlignedLabelContainer : UIView { } @end @implementation TopAlignedLabelContainer - (void)layoutSubviews { CGRect bounds = self.bounds; for (UILabel *label in [self subviews]) { if ([label isKindOfClass:[UILabel class]]) { CGSize fontSize = [label.text sizeWithFont:label.font]; CGSize textSize = [label.text sizeWithFont:label.font constrainedToSize:bounds.size lineBreakMode:label.lineBreakMode]; label.numberOfLines = textSize.height / fontSize.height; label.frame = CGRectMake(0, 0, textSize.width, fontSize.height * label.numberOfLines); } } } @end 

Puede usar TTTAttributedLabel , admite alineación vertical.

 @property (nonatomic) TTTAttributedLabel* label; < ...> //view's or viewController's init method _label.verticalAlignment = TTTAttributedLabelVerticalAlignmentTop; 

He encontrado que las respuestas a esta pregunta ahora están un poco desactualizadas, por lo que agrego esto para los fanáticos del diseño automático.

El diseño automático hace que este problema sea bastante trivial. Suponiendo que UIView *view la etiqueta a la UIView *view , el siguiente código logrará esto:

 UILabel *label = [[UILabel alloc] initWithFrame:CGRectZero]; [label setText:@"Some text here"]; [label setTranslatesAutoresizingMaskIntoConstraints:NO]; [view addSubview:label]; [view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[label]|" options:0 metrics:nil views:@{@"label": label}]]; [view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[label]" options:0 metrics:nil views:@{@"label": label}]]; 

La altura de la etiqueta se calculará automáticamente (utilizando su valor intrinsicContentSize ) y la etiqueta se colocará borde a borde horizontalmente, en la parte superior de la view .

Quería tener una etiqueta que pudiera tener líneas múltiples, un tamaño mínimo de fuente y centrado tanto horizontal como verticalmente en su vista principal. Agregué mi etiqueta programáticamente a mi vista:

 - (void) customInit { // Setup label self.label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)]; self.label.numberOfLines = 0; self.label.lineBreakMode = UILineBreakModeWordWrap; self.label.textAlignment = UITextAlignmentCenter; // Add the label as a subview self.autoresizesSubviews = YES; [self addSubview:self.label]; } 

Y luego, cuando quise cambiar el texto de mi etiqueta …

 - (void) updateDisplay:(NSString *)text { if (![text isEqualToString:self.label.text]) { // Calculate the font size to use (save to label's font) CGSize textConstrainedSize = CGSizeMake(self.frame.size.width, INT_MAX); self.label.font = [UIFont systemFontOfSize:TICKER_FONT_SIZE]; CGSize textSize = [text sizeWithFont:self.label.font constrainedToSize:textConstrainedSize]; while (textSize.height > self.frame.size.height && self.label.font.pointSize > TICKER_MINIMUM_FONT_SIZE) { self.label.font = [UIFont systemFontOfSize:self.label.font.pointSize-1]; textSize = [ticker.blurb sizeWithFont:self.label.font constrainedToSize:textConstrainedSize]; } // In cases where the frame is still too large (when we're exceeding minimum font size), // use the views size if (textSize.height > self.frame.size.height) { textSize = [text sizeWithFont:self.label.font constrainedToSize:self.frame.size]; } // Draw self.label.frame = CGRectMake(0, self.frame.size.height/2 - textSize.height/2, self.frame.size.width, textSize.height); self.label.text = text; } [self setNeedsDisplay]; } 

Espero que ayude a alguien!

FXLabel (en github) hace esto de label.contentMode al configurar label.contentMode en UIViewContentModeTop . Este componente no está hecho por mí, pero es un componente que uso con frecuencia y tiene muchas características, y parece funcionar bien.

He usado muchos de los métodos anteriores y solo quiero agregar un enfoque rápido y sucio que he usado:

 myLabel.text = [NSString stringWithFormat:@"%@\n\n\n\n\n\n\n\n\n",@"My label text string"]; 

Asegúrese de que el número de nuevas líneas en la cadena hará que cualquier texto llene el espacio vertical disponible, y configure el UILabel para truncar cualquier texto desbordado.

Porque a veces lo suficientemente bueno es lo suficientemente bueno .

para cualquiera que lea esto porque el texto dentro de su etiqueta no está verticalmente centrado, tenga en cuenta que algunos tipos de fonts no están diseñados por igual. por ejemplo, si crea una etiqueta con zapfino tamaño 16, verá que el texto no está perfectamente centrado verticalmente.

sin embargo, trabajar con helvetica centrará verticalmente su texto.

Subclase UILabel y restringe el rectángulo de dibujo, como este:

 - (void)drawTextInRect:(CGRect)rect { CGSize sizeThatFits = [self sizeThatFits:rect.size]; rect.size.height = MIN(rect.size.height, sizeThatFits.height); [super drawTextInRect:rect]; } 

Intenté la solución que implicaba relleno de nueva línea y encontré un comportamiento incorrecto en algunos casos. En mi experiencia, es más fácil restringir el trazado de dibujo que el anterior con numberOfLines .

PD: Puedes imaginarte fácilmente apoyando UIViewContentMode de esta manera:

 - (void)drawTextInRect:(CGRect)rect { CGSize sizeThatFits = [self sizeThatFits:rect.size]; if (self.contentMode == UIViewContentModeTop) { rect.size.height = MIN(rect.size.height, sizeThatFits.height); } else if (self.contentMode == UIViewContentModeBottom) { rect.origin.y = MAX(0, rect.size.height - sizeThatFits.height); rect.size.height = MIN(rect.size.height, sizeThatFits.height); } [super drawTextInRect:rect]; } 

Si está utilizando el diseño automático, establezca el contenido vertical HuggingPriority en 1000, ya sea en código o IB. En IB, puede que tenga que eliminar una restricción de altura estableciendo su prioridad en 1 y luego eliminándola.

Siempre que no esté realizando ninguna tarea compleja, puede usar UITextView lugar de UILabels .

Desactivar el desplazamiento.

Si desea que el texto se muestre por completo solo user sizeToFit y sizeThatFits: methods

Si crear una vista personalizada es una opción, podría hacer algo como esto:

 - (void)drawRect:(CGRect)rect { CGRect bounds = self.bounds; [self.textColor set]; [self.text drawInRect:bounds withFont:self.font lineBreakMode:UILineBreakModeTailTruncation alignment:self.textAlignment]; } 

En UILabel, la alineación de texto verticalmente no es posible. Sin embargo, puede cambiar dinámicamente la altura de la etiqueta utilizando sizeWithFont: método de NSString , y simplemente configure su xey como lo desee.

Puede usar UITextField . Es compatible con la propiedad contentVerticalAlignment, ya que es una subclase de UIControl . userInteractionEnabled establecer su userInteractionEnabled en NO para evitar que el usuario escriba texto en él.

I know this is an old post but vertically aligning text is a HUGE problem (at least for me it is) and I figured that I should share this solution since I couldn’t find one myself.

Using drawRect is a little expensive in my opinion. The proper way to get a UILabel to vertically align is to not use a UILabel. Use a UITextView (multiline UITextField) and observe the content property like so:

 - (UITextView*)textView{ if(!_textView){ UIEdgeInsets insets = UIEdgeInsetsMake(0, 50, 0, 5); CGRect frame = CGRectMake(0.0f, 0.0f, 100.0f, 100.0f); _textView = [[UITextView alloc]initWithFrame:UIEdgeInsetsInsetRect(frame, insets)]; _textView.delegate = self; _textView.scrollEnabled = YES; _textView.bounces = YES; _textView.backgroundColor = [UIColor whiteColor]; [_textView setUserInteractionEnabled:NO]; [_textView addObserver:self forKeyPath:@"contentSize" options:(NSKeyValueObservingOptionNew) context:NULL]; } return _textView; } -(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change: (NSDictionary *)change context:(void *)context { UITextView *tv = object; CGFloat height = [tv bounds].size.height; CGFloat contentheight; #ifdef __IPHONE_7_0 contentheight = [tv sizeThatFits:CGSizeMake(tv.frame.size.width, FLT_MAX)].height; #else contentheight = [tv contentSize].height; #endif switch(self.verticalAlignment) { case VerticalAlignmentBottom:{ CGFloat topCorrect = ([tv bounds].size.height - contentheight); topCorrect = (topCorrect <0.0 ? 0.0 : topCorrect); tv.contentOffset = (CGPoint){.x = 0, .y = -topCorrect}; } break; case VerticalAlignmentMiddle:{ CGFloat topCorrect = (height - contentheight * [tv zoomScale])/2.0; topCorrect = ( topCorrect < 0.0 ? 0.0 : topCorrect ); tv.contentOffset = (CGPoint){.x = 0, .y = -topCorrect}; } break; case VerticalAlignmentTop:{ tv.contentOffset = (CGPoint){.x = 0, .y = 0 }; } break; default: break; } } 

Basically what's happening here is we set the class we're in as the observer, looking at the contentSize property with an option of NSKeyValueObservingOptionNew so every time the content changes, -(void)observeValueForKeyPath:ofObject:change:context: will get called and then you can calculate an offset size to align the text appropriately.

I can't take credit for this, the original idea came from here . But, this solution doesn't work on iOS7. After trolling around SO for a few hours, I found this: iOS 7 vertical alignment fix . The key line there is contentheight = [tv sizeThatFits:CGSizeMake(tv.frame.size.width, FLT_MAX)].height; . For some reason in iOS 7, getting the contentSize height doesn't work but that fixes it. Neither of the two solutions worked on their own but after a little tinkering, I was able to synthesize together the above solution.

In swift,

let myLabel : UILabel!

To make your text of your Label to fit to screen and it’s on the top

myLabel.sizeToFit()

To make your font of label to fit to the width of screen or specific width size.

myLabel.adjustsFontSizeToFitWidth = YES

and some textAlignment for label :

myLabel.textAlignment = .center

myLabel.textAlignment = .left

myLabel.textAlignment = .right

myLabel.textAlignment = .Natural

myLabel.textAlignment = .Justified