I am trying to vertically align the text in the UILabel view of my app. The problem is that I want the text to be vertically aligned to the top and the size of the label to
You can do it as follows.......
Set your label's numberOfLines
property 0 from IB
Set your label's lineBreakMode
as UILineBreakModeWordWrap
(very very important)
now whatever you set on the label just append few @"\n" to it..... ex.-
[yourTextLabel setText:@"myLabel\n\n\n\n\n"];
There's a way without subclassing, using a button or rolling your own.
set the number of lines to 0, then call sizeToFit.
[label setNumberOfLines:0];
[label sizeToFit];
More details here as i think someone else linked to: Vertically align text to top within a UILabel
You can make it with a constraint on the interface builder.
Hope this help you !
In Swift, JRC’s solution of subclassing UILabel
, overriding drawTextInRect
and conforming to UIViewContentMode
would 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)
}
}
Implementing is simply a matter of:
yourLabel.contentMode = UIViewContentMode.top
For me, it worked like a charm.
I'm the author of FXLabel, and whilst I don't know Manish, I believe he was trying to help (if he was advertising for me, I certainly didn't ask him to, and I'm not paying him - sorry Manish!).
One of FXLabel's features is that it respects the UIContentMode property of the label, as set in Interface builder. This means you can set label.contentMode = UIViewContentModeTop; to align the text to the top of the label view (which doesn't work for a regular UILabel). The relevant example is here:
https://github.com/nicklockwood/FXLabel/tree/master/Examples/Text%20Alignment
FXLabel is a drop-in subclass of UILabel, so I think it's a pretty good solution for the question being posed. However if the poster would rather solve the problem without using a 3rd party library (which is understandable) then here is the code to do it:
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 untested, so apologies if there are any typos)
You'll need to subclass UILabel. Try this:
- (void)drawTextInRect:(CGRect)rect
{
CGSize sizeThatFits = [self sizeThatFits:rect.size];
rect.size.height = MIN(rect.size.height, sizeThatFits.height);
[super drawTextInRect:rect];
}
As you've discovered, UILabel vertically centers text within its bounds. Here we ask -sizeThatFits
for the text block size and uses it to constrain the drawing rectangle passed to UILabel, so that text is drawn from the top of the label bounds.
You could even support the ignored (sigh) contentMode
property like this:
- (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's a bunch of other solutions and discussion here: Vertically align text to top within a UILabel