Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iOS: multiline uilabel only shows one line with autolayout

Tags:

ios

autolayout

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)]];
like image 831
ckh Avatar asked Feb 24 '13 23:02

ckh


2 Answers

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;
}
like image 110
rdelmar Avatar answered Sep 18 '22 08:09

rdelmar


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
like image 29
mon4goos Avatar answered Sep 19 '22 08:09

mon4goos