UILabel Vertical Alignment

I am trying to vertically align text in the UILabel view of my application. The problem is that I want the text to be vertically aligned at the top and the label size 280 x 150. I can only achieve one of these two things. If I delete the line

[myLabel sizeToFit]; 

then text alignment is ok, but the size is messed up. But if I add the above line, the alignment will be messed up, but the size is fine. How to fix this problem.

I added the code below -

 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]; 
+9
ios uilabel xcode
Jun 29 '12 at 10:16
source share
8 answers

I am the author of FXLabel, and while I do not know Manish, I believe that he tried to help (if he advertised me, I certainly did not ask him, and I do not pay him - sorry Manish!).

One of the functions of FXLabel is that it respects the UIContentMode property of the label, as set in the interface builder. This means that you can set label.contentMode = UIViewContentModeTop; to align the text at the top of the label label (which does not work for regular UILabel). Example:

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

FXLabel is a podcast in UILabel, so I think this is a pretty good solution to the question. However, if the poster is more likely to solve the problem without using a third-party library (which is understandable), then here is the code for this:

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

Note: (This is unverified, so apologize if there are any typos)

+13
Jul 01 2018-12-12T00:
source share

Do not use UILabel for this. Use UIButton with UserInteractionEnabled = NO; and it has options for vertical or horizontal alignment of the text inside it.

Here you go:

 [btnDetail.titleLabel setNumberOfLines:5]; [btnDetail.titleLabel setLineBreakMode:NSLineBreakByCharWrapping]; [btnDetail setContentVerticalAlignment:UIControlContentVerticalAlignmentTop]; [btnDetail setContentHorizontalAlignment:UIControlContentHorizontalAlignmentLeft]; [btnDetail setUserInteractionEnabled:NO]; btnDetail.autoresizesSubviews = YES; btnDetail.autoresizingMask = UIViewAutoresizingFlexibleWidth; 
+16
Mar 28 '13 at 8:23
source share

You need to subclass UILabel. Try the following:

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

As you have discovered, UILabel vertically centers the text within its borders. Here we ask -sizeThatFits for the size of the text block and use it to limit the rectangle of the drawing passed to the UILabel, so that the text is drawn from the top border of the label.

You can even support the ignored (sigh) contentMode as follows:

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

There are several other solutions and discussions here: Vertically align text at the top in UILabel

+11
Jul 03 2018-12-12T00:
source share

In Swift, a subclass of UILabel JRCs that overrides drawTextInRect and the corresponding UIViewContentMode will look like this:

 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) } } 

Implementation is just a question:

 yourLabel.contentMode = UIViewContentMode.top 

For me it worked like a charm.

+8
Mar 21 '15 at 16:12
source share

There is a way without a subclass using a button or rewinding your own.

set the number of rows to 0, then call sizeToFit.

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

More details here, as I think someone else is related to: Vertically align text at the top in UILabel

+1
Aug 22 '13 at 14:33
source share

You can do this with a restriction on the interface builder.

  • Put the number of lines you want
  • Create a constraint with a height large enough for 3 lines, and in the Relationships section, set β€œLess than or equal to”.

Hope this helps you!

+1
Oct 26 '16 at 13:46 on
source share

I did what you need by implementing the category:

.h

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

.m

 @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 

Remember that you need to set "NumberOfLines" to 0. This example works with multi-line parameters!

After implementing the above category, you can simply do:

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

Hurrah!

0
Aug 23 '14 at
source share

You can do it as follows:

  • Set label numberOfLines property 0 from IB

  • Set the lineBreakMode label as UILineBreakModeWordWrap ( very important )

now everything that you installed on the shortcut just adds a few @ "\ n" to it ..... ex.-

 [yourTextLabel setText:@"myLabel\n\n\n\n\n"]; 
-2
Oct 17 '13 at 20:57
source share



All Articles