Reputation: 3318
I know how to set the vertical alignment of a button with IB; see here. But I can not do it programmatically... This is one of the things I have tried:
UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(10, 10, 110, 130)];
[button setTitle:@"Align" forState:UIControlStateNormal];
button.backgroundColor = [UIColor whiteColor];
button.titleLabel.textColor = [UIColor grayColor];
[button setContentVerticalAlignment:UIControlContentVerticalAlignmentBottom];
[self.view addSubview:button];
[button release];
I have also tried insets...
But the alignment won't change.
Please note that I want to keep the CustomStyle of the button (I don't want the default look and feel).
Upvotes: 24
Views: 35853
Reputation: 6559
I've tried the UIEdgeInset changes that are described above but they ended up breaking the LayoutConstraints for my view. So I came up with another solution which is subclassing the UIButton and adding a UILabel to the bottom of it and attaching constraints to that. Here is my solution if anyone wants to go this route:
class VerticalButton: UIButton {
lazy var verticalTitleLabel: UILabel = {
let label = UILabel().autolayout()
label.font = ScaledFont.shared.font(forTextStyle: .body)
label.numberOfLines = 0
label.textColor = .white
return label
}()
required init?(coder: NSCoder) {
super.init(coder: coder)
commonInit()
}
override init(frame: CGRect) {
super.init(frame: frame)
commonInit()
}
convenience init(title: String) {
self.init(frame: .zero)
verticalTitleLabel.text = title
}
private func commonInit() {
setTitle(nil, for: .normal) // Set the original title to nil so it doesn't show
addSubview(verticalTitleLabel)
NSLayoutConstraint.activate([
verticalTitleLabel.bottomAnchor.constraint(equalTo: bottomAnchor),
verticalTitleLabel.centerXAnchor.constraint(equalTo: centerXAnchor),
verticalTitleLabel.heightAnchor.constraint(greaterThanOrEqualToConstant: 25.0)
])
}
override func setTitle(_ title: String?, for state: UIControl.State) {
super.setTitle("", for: state)
verticalTitleLabel.text = title
}
}
Upvotes: 0
Reputation: 1215
I found a better way that works for me. I'm using a custom font so the alignment went a bit off by a few like in lindon fox's answer above.
Inside of you UIButton subclass:
- (void)layoutSubviews {
[super layoutSubviews];
if (UIEdgeInsetsEqualToEdgeInsets(UIEdgeInsetsZero, self.titleEdgeInsets)) {
// adjust top, left bottom, and right to fit your needs
self.titleEdgeInsets = UIEdgeInsetsMake(top, left, bottom, right);
}
}
I agree with the other answers that using the contentVerticalAlignment
set to UIControlContentVerticalAlignmentCenter
is also a good idea.
Upvotes: 0
Reputation: 2551
You can alignment (horizontal and vertical) the text of button in this way:
UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 200, 70)];
button.backgroundColor = [UIColor whiteColor];
button.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft;
button.contentVerticalAlignment = UIControlContentVerticalAlignmentBottom;
[button setTitle:@"Align" forState:UIControlStateNormal];
[self.container addSubview:button];
Upvotes: 27
Reputation: 884
You can easily manipulate inner text label of UIButton. Here how you can do it:
Upvotes: 1
Reputation: 3318
The problem was the using
button.titleLabel.textColor = [UIColor grayColor];
instead of
[button setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
Elsewhere in my code I am still having troubles vertically aligning the text, but I have got the basic example going, so I should be able to get the more complicated version going if I look at it more. Perhaps there are other methods I am using like button.titleLabel.textColor which make the vertical alignment not work...
Update The original problem was actually because my button was too short (button height).
The word husband
is in the button, which is currently vertically aligned to the bottom. But since the height of the button is not enough, it is not obvious. Even though the default of the title insets and content insets are zero, it does not seem like the title can be flush against the bottom. It looks like about 5 pixels to me. I tested with a smaller font to make sure this is correct.
Unfortunately vertically aligning the text to the top does not seem to change anything...
Upvotes: 1
Reputation: 21967
contentVerticalAlignment
is the way to go. Could be how you're creating the button. Try this:
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
button.frame = CGRectMake(10, 10, 110, 130);
// rest of your code
// don't release button explicitly
Upvotes: 9