Reputation: 1834
How the UILabel
can be aligned from bottom. Let say, my label can hold three line of text.If the input text is single line, then this line should come bottom of the label.Please refer the below image for better understanding. The orange area is the full frame of label.Currently it has one line and it is aligned center. So what I want is, it should always aligned bottom regardless of how many lines.
Please suggest your ideas.
Thank you.
Upvotes: 49
Views: 53245
Reputation: 1581
class VerticalAlignedLabel: UILabel {
let bottomSpacing: CGFloat = 10.0
override func drawText(in rect: CGRect) {
var newRect = rect
let height = sizeThatFits(rect.size).height
newRect.origin.y = rect.origin.y + rect.size.height - height - bottomSpacing
newRect.size.height = height
super.drawText(in: newRect)
}
}
Upvotes: 0
Reputation: 845
Swift 5 version of @Dustin code:
Subclass:
class VerticallyAlignedUILabel: UILabel {
enum Alignment {
case top
case bottom
}
var alignment: Alignment = .top
override func drawText(in rect: CGRect) {
var rect = rect
if alignment == .top {
rect.size.height = sizeThatFits(rect.size).height
} else if alignment == .bottom {
let height = sizeThatFits(rect.size).height
rect.origin.y += rect.size.height - height
rect.size.height = height
}
super.drawText(in: rect)
}
}
Usage:
let myLabel = VerticallyAlignedUILabel()
myLabel.text = "vertically aligned text"
myLabel.alignment = .bottom
Upvotes: 1
Reputation: 101
Put your UILabel in a vertical UIStackView with a dummy view as a spacer. Also, set the dummy view with a lower hugging and compression priority.
Top to Bottom:
Bottom to Top:
Upvotes: 1
Reputation: 451
Swift 4.2 version using the contentMode
property to set top and bottom:
class VerticalAlignedLabel: UILabel {
override func drawText(in rect: CGRect) {
var newRect = rect
switch contentMode {
case .top:
newRect.size.height = sizeThatFits(rect.size).height
case .bottom:
let height = sizeThatFits(rect.size).height
newRect.origin.y += rect.size.height - height
newRect.size.height = height
default:
()
}
super.drawText(in: newRect)
}
}
Then setup your label like that:
let label = VerticalAlignedLabel()
label.contentMode = .bottom
Upvotes: 30
Reputation: 1
textLabel.numberOfLines = 0
textLabel.textAlignment = .center
textLabel.topAnchor.constraint(greaterThanOrEqualTo: sView.topAnchor).isActive = true
textLabel.leadingAnchor.constraint(equalTo: sView.leadingAnchor).isActive = true
textLabel.trailingAnchor.constraint(equalTo: sView.trailingAnchor).isActive = true
textLabel.bottomAnchor.constraint(equalTo: sView.bottomAnchor).isActive = true
Upvotes: -2
Reputation: 1119
I recently ran into this problem and was able to solve it by putting my label in a stackview by itself. I got the idea from this post which had the same question but with multiple labels. The same technique can be used with a single label.
The stackview would have axis = horizontal and alignment = bottom (which is what does the trick).
My label is now perfectly aligned towards the bottom which is what I needed.
Upvotes: 2
Reputation: 11
In IB as @Tobe said Bottom constraint to superview should work,
Incase if you have multiple subview or horizontal stack view with one element to have bottom constraint then use Layout Margin to be Fixed with bottom less than other margins
Upvotes: 0
Reputation: 20551
Here are two ways of doing that...
1. First set numberOfLines
to 0 and then use sizeToFit
property of UILabel
so your UILabel
display with its contentSize
.
yourLabel.numberOfLines = 0;
[yourLabel sizeToFit];
See more information from this link: Vertically align text within a UILabel
2. Another option is to take UITextField
instead of UILabel
and set userInteractionEnabled
to NO
like below...
[yourTextField setUserInteractionEnabled:NO];
and then set the contentVerticalAlignment
property to bottom like below...
[yourTextField setContentVerticalAlignment:UIControlContentVerticalAlignmentBottom];
UPDATE
Also, with UITextField
, we can't achieve multiple lines. So instead we can use UITextView
and set its userInteractionEnabled
to NO
. Then, use the code below to make it bottom aligned.
CGFloat topCorrect = ([label bounds].size.height - [label contentSize].height);
topCorrect = (topCorrect <0.0 ? 0.0 : topCorrect);
label.contentOffset = (CGPoint){.x = 0, .y = -topCorrect};
Upvotes: 24
Reputation: 518
i only set a bottom constraint to the super view in IB which works for me without using code and also number of Lines for a maximum constraint.
Upvotes: 3
Reputation: 313
You can subclass UILabel
and overriding the method :
- (void)drawTextInRect:(CGRect)rect
call super drawTextInRect
with the rect where you want to use.
Upvotes: -2
Reputation: 261
Another option: use one label for your background color, I call this one originalLabel, and another for the text, called textLabel in my example. Then calculate the height and Y coordinate for textLabel:
[textLabel sizeToFit];
int height = textLabel.frame.size.height;
int yCoord = originalLabel.frame.origin.y +
originalLabel.frame.size.height - height;
textLabel.frame = CGRectMake( originalLabel.frame.origin.x, yCoord,
textLabel.frame.size.width, height);
Upvotes: 0
Reputation: 1801
I had the same issue. Here is how I made to align the text to the bottom of my UILabel:
- (void)alignLabel:(UILabel *)l withText:(NSString *)text verticalAlignOption:(int)vertAlign{
CGSize stringSize = [text sizeWithFont:l.font constrainedToSize:l.frame.size lineBreakMode:l.lineBreakMode];
switch (vertAlign) {
case 0: // align = top
l.frame = CGRectMake(l.frame.origin.x,
l.frame.origin.y,
l.frame.size.width,
stringSize.height
);
break;
case 1: // align = bottom
l.frame = CGRectMake(l.frame.origin.x,
(l.frame.origin.y + l.frame.size.height) - stringSize.height,
l.frame.size.width,
stringSize.height
);
break;
case 2: // align = middle
// default
break;
}
l.text = text;
}
Ahd you simple call the method like this to align to the bottom:
[self alignLabel:self.mediaTitle withText:@"My text to align" verticalAlignOption:1];
Upvotes: 0
Reputation: 1030
Subclass UILabel
@interface Label : UILabel
@end
Then override drawTextInRect like so
@implementation Label
- (void)drawTextInRect:(CGRect)rect
{
if(alignment == top) {
rect.size.height = [self sizeThatFits:rect.size].height;
}
if(alignment == bottom) {
CGFloat height = [self sizeThatFits:rect.size].height;
rect.origin.y += rect.size.height - height;
rect.size.height = height;
}
[super drawTextInRect:rect];
}
@end
Upvotes: 20