The code below, I think should result iin a multiline label followed by a button, however, after layout there is only a single line of the label showing up. While I could put an explicit height in the vertical layout that would defeat the purpose. Any ideas about what other constraints I should apply?
UILabel *lbExplain = [[UILabel alloc] init];
lbExplain.text = @"The Sync process allows you to synchronize your library between different devices. By clicking on the button below you can find other devices to sync with. The other device also has to be running this applicaton.";
lbExplain.lineBreakMode = NSLineBreakByWordWrapping;
lbExplain.numberOfLines = 0;
lbExplain.translatesAutoresizingMaskIntoConstraints = NO;
UIButton *btnPartner = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[btnPartner setTitle:@"Look for Partners" forState:UIControlStateNormal];
[btnPartner addTarget:self action:@selector(findPartners:) forControlEvents:UIControlEventTouchUpInside];
btnPartner.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:lbExplain];
[self.view addSubview:btnPartner];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-[lbExplain]-|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(lbExplain)]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-[lbExplain]-[btnPartner]" options:NSLayoutFormatAlignAllLeft metrics:nil views:NSDictionaryOfVariableBindings(lbExplain, btnPartner)]];
Add the line:
lbExplain.preferredMaxLayoutWidth = 280;
This must be something that is done automatically in IB, since the label expands properly if you set it up there. The number you pass it does seem to matter some in how it expands vertically, but it doesn't override the constraints you set for the width.
After Edit:
It works better if I add that line in updateViewConstraints, and relate the number to the view's bounds. This way it adjusts properly on rotation.
-(void)updateViewConstraints {
[super updateViewConstraints];
lbExplain.preferredMaxLayoutWidth = self.view.bounds.size.width - 40;
}
The issue here is that preferredMaxLayoutWidth
is not set. As a result, the text is not constrained by any width and, as such, it does not wrap to the next line.
I've found that the easiest way to use a multiline UILabel
with Autolayout is to create a subclass:
@interface MyMultilineLabel : UILabel
@end
@implementation MyMultilineLabel
- (void)setBounds:(CGRect)bounds {
[super setBounds:bounds];
CGFloat width = CGRectGetWidth(bounds);
if (self.preferredMaxLayoutWidth != width) {
self.preferredMaxLayoutWidth = width;
}
}
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
self.lineBreakMode = NSLineBreakByWordWrapping;
self.numberOfLines = 0;
}
return self;
}
@end
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With