IOS: многострочный uilabel показывает только одну строку с автозапуском

Код ниже, я думаю, должен получиться в многострочной метке, за которой следует кнопка, однако после компоновки появляется только одна строка метки. Хотя я мог бы установить явную высоту в вертикальной компоновке, которая могла бы победить цель. Любые идеи о том, какие другие ограничения я должен применять?

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)]];

Ответы

Ответ 1

Добавьте строку:

lbExplain.preferredMaxLayoutWidth = 280;

Это должно быть что-то, что делается автоматически в IB, поскольку ярлык правильно расширяется, если вы его там установили. Число, которое вы передаете, похоже, имеет значение для того, как оно расширяется по вертикали, но оно не отменяет ограничений, заданных для ширины.

После редактирования:

Он работает лучше, если я добавляю эту строку в updateViewConstraints и свяжу номер с границами представления. Таким образом, он правильно регулируется при вращении.

-(void)updateViewConstraints {
    [super updateViewConstraints];
    lbExplain.preferredMaxLayoutWidth = self.view.bounds.size.width - 40;
}

Ответ 2

Проблема здесь в том, что preferredMaxLayoutWidth не установлен. В результате текст не ограничен какой-либо шириной и, как таковой, не переносится на следующую строку.

Я обнаружил, что самый простой способ использования многострочного UILabel с Autolayout - создать подкласс:

@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

Ответ 3

Вы уверены, что у вас нет двусмысленного макета?

вы можете сделать тест в своем коде, например

if ([self.view hasAmbiguousLayout]) {
    NSLog(@"ambiguous");
}

или сделать паузу на тренажере или тестовом устройстве и ввести консоль:

po [[UIWindow keyWindow] _autolayoutTrace]

если это так, вы можете попытаться сделать ваши противоречия более явными (на первый взгляд, высота неоднозначна):

@"V:|-[lbExplain]-[btnPartner]-|"

или

@"V:|-[lbExplain(==300)]-[btnPartner(==200)]"

вот документация на язык визуального формата:

http://developer.apple.com/library/mac/#documentation/UserExperience/Conceptual/AutolayoutPG/Articles/formatLanguage.html

Ответ 4

У меня была аналогичная проблема, когда многострочная метка в UITableViewCell, размещенная с помощью AutoLayout, не расширила бы себя.

Он находился в настройках UITableView "автоматически" с помощью метода UITableViewAutomaticDimension и methodHeightForRowAtIndexPath. (Я думаю, что это может быть источником проблемы)

Я понял эту проблему, позвонив:

[cell layoutIfNeeded]

в методе cellForRowAtIndexPath, как раз перед возвратом ячейки.

И это сработало как шарм!