Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Vertically align text within a UILabel (Note : Using AutoLayout)

I am Copying the same Question asked Before Question. I have tried the solutions given and was not able to solve it since sizetofit was not effective when I use Autolayout.

first screenshot

The expected display is like below.

second screenshot

like image 796
MELWIN Avatar asked Feb 19 '15 11:02

MELWIN


People also ask

How do you align text on top of UILabel?

Set the UIView constraints to occupy the maximum space the UILabel should grow to. Then set the UILabel to top, right, and left of the UIView and set a constraint also to bottom with distance >= 0 .

How do you align text vertically in container flutter?

In Flutter, to vertically center a child widget inside a Container, you can wrap the child widget with Column and add mainAxisAlignment: MainAxisAlignment. center to it.

How do I center text vertically in react native?

To put a Text component vertically and horizontally center of View component in RN we have to use justifyContent: 'center' and alignItems: 'center' layout styles.


2 Answers

Edit

In my original answer I was using the paragraph style of the label. Turns out that for multi-line labels this actually prevents the label from being multi-line. As a result I removed it from the calculation. See more about this in Github

For those of you more comfortable with using Open Source definitely look at TTTAttributedLabel where you can set the label's text alignment to TTTAttributedLabelVerticalAlignmentTop


The trick is to subclass UILabel and override drawTextInRect. Then enforce that the text is drawn at the origin of the label's bounds.

Here's a naive implementation that you can use right now:

Swift

@IBDesignable class TopAlignedLabel: UILabel {     override func drawTextInRect(rect: CGRect) {         if let stringText = text {             let stringTextAsNSString = stringText as NSString             var labelStringSize = stringTextAsNSString.boundingRectWithSize(CGSizeMake(CGRectGetWidth(self.frame), CGFloat.max),                 options: NSStringDrawingOptions.UsesLineFragmentOrigin,                 attributes: [NSFontAttributeName: font],                 context: nil).size             super.drawTextInRect(CGRectMake(0, 0, CGRectGetWidth(self.frame), ceil(labelStringSize.height)))         } else {             super.drawTextInRect(rect)         }     }     override func prepareForInterfaceBuilder() {         super.prepareForInterfaceBuilder()         layer.borderWidth = 1         layer.borderColor = UIColor.blackColor().CGColor     } } 

Swift 3

  @IBDesignable class TopAlignedLabel: UILabel {     override func drawText(in rect: CGRect) {         if let stringText = text {             let stringTextAsNSString = stringText as NSString             let labelStringSize = stringTextAsNSString.boundingRect(with: CGSize(width: self.frame.width,height: CGFloat.greatestFiniteMagnitude),                                                                             options: NSStringDrawingOptions.usesLineFragmentOrigin,                                                                             attributes: [NSFontAttributeName: font],                                                                             context: nil).size             super.drawText(in: CGRect(x:0,y: 0,width: self.frame.width, height:ceil(labelStringSize.height)))         } else {             super.drawText(in: rect)         }     }     override func prepareForInterfaceBuilder() {         super.prepareForInterfaceBuilder()         layer.borderWidth = 1         layer.borderColor = UIColor.black.cgColor     } } 

Objective-C

IB_DESIGNABLE @interface TopAlignedLabel : UILabel  @end  @implementation TopAlignedLabel  - (void)drawTextInRect:(CGRect)rect {     if (self.text) {         CGSize labelStringSize = [self.text boundingRectWithSize:CGSizeMake(CGRectGetWidth(self.frame), CGFLOAT_MAX)                                                          options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading                                                       attributes:@{NSFontAttributeName:self.font}                                                          context:nil].size;         [super drawTextInRect:CGRectMake(0, 0, ceilf(CGRectGetWidth(self.frame)),ceilf(labelStringSize.height))];     } else {         [super drawTextInRect:rect];     } }  - (void)prepareForInterfaceBuilder {         [super prepareForInterfaceBuilder];         self.layer.borderWidth = 1;         self.layer.borderColor = [UIColor blackColor].CGColor; }  @end 

Since I used IBDesignable you can add this label to a storyboard and watch it go, this is what it looks like for me

enter image description here

like image 107
Daniel Galasko Avatar answered Oct 10 '22 20:10

Daniel Galasko


If you're not restricted by having UILabel of fixed size, instead of aligning the text within a UILabel, simply use ≥ constraint on the given label to change the size of it.

enter image description here

It's the most elegant solution using Auto Layout. Don't forget to set numberOfLines to zero though.

like image 28
Nikola Milicevic Avatar answered Oct 10 '22 22:10

Nikola Milicevic