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
I did it what you want by implementing a 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 multilines options!
After you implement above category, you can simply do:
[myLabel setText:finalRecipe];
[myLabel alignTop];
Cheers!
nice hack... my two cents for swift 4.2/5:
self.optTextMessage.numberOfLines = 0
self.optTitle.lineBreakMode = .byWordWrapping
and add \n.. as suggested..
dont use UILabel
for this. Use UIButton
with UserInteractionEnabled = NO;
and that has options to vertical or horizontal align text inside it.
Here you go:
btnDetail.titleLabel?.numberOfLines = 5
btnDetail.titleLabel?.lineBreakMode = .byCharWrapping
btnDetail.contentVerticalAlignment = .top
btnDetail.contentHorizontalAlignment = .left
btnDetail.isUserInteractionEnabled = false
btnDetail.autoresizesSubviews = true
btnDetail.autoresizingMask = .flexibleWidth
[btnDetail.titleLabel setNumberOfLines:5];
[btnDetail.titleLabel setLineBreakMode:NSLineBreakByCharWrapping];
[btnDetail setContentVerticalAlignment:UIControlContentVerticalAlignmentTop];
[btnDetail setContentHorizontalAlignment:UIControlContentHorizontalAlignmentLeft];
[btnDetail setUserInteractionEnabled:NO];
btnDetail.autoresizesSubviews = YES;
btnDetail.autoresizingMask = UIViewAutoresizingFlexibleWidth;
In addition to the above recommending setting the number of lines to 0 and the line break to Word Wrap be sure to not specify a height constraint. New lines are automatically added as needed by the displayed text and the text is always vertically aligned to the top of the label.