Vertically align UILabel

Estoy intentando alinear verticalmente el text en la vista UILabel de mi aplicación. El problema es que quiero que el text esté alineado verticalmente a la parte superior y que el tamaño de la label sea de 280 x 150. Solo puedo lograr una de estas dos cosas. Si elimino la línea

[myLabel sizeToFit]; 

entonces la alignment del text está bien pero el tamaño está en mal estado. Pero si agrego la línea anterior, entonces la alignment está desorderada pero el tamaño está bien. ¿Cómo soluciono este problema?

He agregado el siguiente código:

 CGRect labelFrame = CGRectMake(22, 50, 280, 150); UILabel *myLabel = [[UILabel alloc] initWithFrame:labelFrame]; [myLabel setText:finalRecipe]; [myLabel setBackgroundColor: [UIColor lightGrayColor]]; [myLabel setNumberOfLines:0]; [myLabel sizeToFit]; [self.view addSubview:myLabel]; 

Soy el autor de FXLabel, y aunque no conozco a Manish, creo que estaba tratando de ayudar (si él me anunciaba, ciertamente no le pedí que lo hiciera, y no le estoy pagando, lo siento Manish!).

Una de las características de FXLabel es que respeta la propiedad UIContentMode de la label, tal como se establece en el generador de interfaces. Esto significa que puede establecer label.contentMode = UIViewContentModeTop; para alinear el text en la parte superior de la vista de label (que no funciona para una UILabel normal). El ejemplo relevante está aquí:

https://github.com/nicklockwood/FXLabel/tree/master/Examples/Text%20Alignment

FXLabel es una subclass drop-in de UILabel, así que creo que es una solución bastante buena para la pregunta que se plantea. Sin embargo, si el póster prefiere resolver el problema sin usar una biblioteca de terceros (lo que es comprensible), aquí está el código para hacerlo:

 CGRect labelFrame = CGRectMake(22, 50, 280, 150); UILabel *myLabel = [[UILabel alloc] initWithFrame:labelFrame]; [myLabel setText:finalRecipe]; [myLabel setBackgroundColor: [UIColor lightGrayColor]]; [myLabel setNumberOfLines:0]; CGFloat fontSize = 0.0f; labelFrame.size = [myLabel.text sizeWithFont:myLabel.font minFontSize:myLabel.minimumFontSize actualFontSize:&fontSize forWidth:labelFrame.width lineBreakMode:myLabel.lineBreakMode]; myLabel.frame = labelFrame; [self.view addSubview:myLabel]; 

Nota: (Esto no se ha probado, así que discúlpese si hay algún error tipográfico)

No uses UILabel para esto. Use el UIButton con UserInteractionEnabled = NO; y que tiene opciones para alinear text vertical u horizontal dentro de él.

Aqui tienes:

 [btnDetail.titleLabel setNumberOfLines:5]; [btnDetail.titleLabel setLineBreakMode:NSLineBreakByCharWrapping]; [btnDetail setContentVerticalAlignment:UIControlContentVerticalAlignmentTop]; [btnDetail setContentHorizontalAlignment:UIControlContentHorizontalAlignmentLeft]; [btnDetail setUserInteractionEnabled:NO]; btnDetail.autoresizesSubviews = YES; btnDetail.autoresizingMask = UIViewAutoresizingFlexibleWidth; 

Deberá subclass UILabel. Prueba esto:

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

Como has descubierto, UILabel centra verticalmente el text dentro de sus límites. Aquí pedimos -sizeThatFits para el tamaño de bloque de text y lo usa para restringir el rectángulo de dibujo pasado a UILabel, de modo que el text se dibuja desde la parte superior de los límites de la label.

Incluso podría admitir la propiedad contentMode ignorada (suspirar) como esta:

 - (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]; } 

Hay un montón de otras soluciones y discusiones aquí: Alinear verticalmente el text hacia arriba dentro de un UILabel

En Swift, la solución del JRC de subclass UILabel , anular drawTextInRect y conformarse a UIViewContentMode se vería así:

 class AlignableUILabel: UILabel { override func drawText(in rect: CGRect) { var newRect = CGRect(x: rect.origin.x,y: rect.origin.y,width: rect.width, height: rect.height) let fittingSize = sizeThatFits(rect.size) if contentMode == UIViewContentMode.top { newRect.size.height = min(newRect.size.height, fittingSize.height) } else if contentMode == UIViewContentMode.bottom { newRect.origin.y = max(0, newRect.size.height - fittingSize.height) } super.drawText(in: newRect) } } 

Implementar es simplemente una cuestión de:

 yourLabel.contentMode = UIViewContentMode.top 

Para mí, funcionó como un encanto.

Hay una forma sin subclasss, con un button o con la suya propia.

establezca el número de líneas en 0, luego llame a sizeToFit.

 [label setNumberOfLines:0]; [label sizeToFit]; 

Más detalles aquí, ya que creo que alguien más vinculado a: Alinear verticalmente el text hacia arriba dentro de un UILabel

Puede hacerlo con una restricción en el generador de interfaces.

  1. Pon la cantidad de líneas que deseas
  2. Cree una restricción con una altura lo suficientemente mayor para 3 líneas y en la sección de relación ponga "Menos o igual".

Espero que esto te ayude!

Lo hice lo que quieres implementando una categoría:

.marido

 @interface UILabel (VerticalAlign) - (void)alignTop; - (void)alignBottom; @end 

.metro

 @implementation UILabel (VerticalAlign) #pragma mark #pragma mark - Align Methods - (void)alignTop { [self setFrame:[self newLabelFrame:UIControlContentVerticalAlignmentTop]]; } - (void)alignBottom { [self setFrame:[self newLabelFrame:UIControlContentVerticalAlignmentBottom]]; } #pragma mark #pragma mark - Helper Methods - (CGRect)newLabelFrame:(UIControlContentVerticalAlignment)alignment { CGRect labelRect = self.frame; NSStringDrawingOptions options = NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingTruncatesLastVisibleLine | NSStringDrawingUsesFontLeading; CGRect textRect = [self.text boundingRectWithSize:CGSizeMake(227.f, CGFLOAT_MAX) options:options attributes:@{NSFontAttributeName:self.font} context:nil]; CGFloat textOffset = labelRect.size.height - textRect.size.height; UIEdgeInsets contentInsets; if (alignment == UIControlContentVerticalAlignmentTop) { if (textOffset < (labelRect.size.height/2.f)) { contentInsets = UIEdgeInsetsMake(-textOffset, 0.f, 0.f, 0.f); } else { contentInsets = UIEdgeInsetsMake(0.f, 0.f, textOffset, 0.f); } } else { if (textOffset < (labelRect.size.height/2.f)) { contentInsets = UIEdgeInsetsMake(0.f, 0.f, -textOffset, 0.f); } else { contentInsets = UIEdgeInsetsMake(textOffset, 0.f, 0.f, 0.f); } } return UIEdgeInsetsInsetRect(labelRect, contentInsets); } @end 

Recuerde que debe configurar "NumberOfLines" en 0. Este ejemplo funciona con opciones de multilíneas.

Después de implementar la categoría anterior, simplemente puede hacer lo siguiente:

 [myLabel setText:finalRecipe]; [myLabel alignTop]; 

¡Aclamaciones!

Puedes hacerlo de la siguiente manera …

  1. Establezca la propiedad numberOfLines su label 0 de IB

  2. Establezca el lineBreakMode su label como UILineBreakModeWordWrap ( muy muy importante )

ahora lo que establezca en la label simplemente agregue unos pocos "\ n" a él ….. ex.-

 [yourTextLabel setText:@"myLabel\n\n\n\n\n"];