UILabel sizeToFit и ограничения

Есть ли какой-либо простой способ, который может помочь мне динамически изменять положение зависимых представлений, используя их размер содержимого?

Я хочу показать несколько просмотров в столбце, в которых все имеют различный контент. И я хочу, чтобы они были размещены один за другим (я создал макет, используя ограничения, которые выглядят так)

initial layout

Но всякий раз, когда я изменяю содержимое меток и вызываю sizeToFit, система, похоже, игнорирует макет.

after size to fit call

В настоящий момент меня интересует только свойство height, я знаю, что ограничение спрятать можно также использовать, и в прошлом я писал много категорий в UIView для динамического изменения размеров (думаю, все сделали). Но может быть, есть простой способ, который я не знаю?

Ответы

Ответ 1

-sizeToFit не следует вызывать, если вы используете автоматическую компоновку. Эта часть "старой" системы.

Похоже, что IB ввел явные высоты в ваши ограничения (вертикальные столбцы рядом с метками указывают на это). Попробуйте выбрать ярлыки и нажать Cmd + =, чтобы очистить их.

Для многострочных этикеток вам также необходимо будет сделать следующее в контроллере просмотра, чтобы все было корректно работать при повороте/изменении размера представления:

- (void)updateLabelPreferredMaxLayoutWidthToCurrentWidth:(UILabel *)label
{
    label.preferredMaxLayoutWidth =
        [label alignmentRectForFrame:label.frame].size.width;
}

- (void)viewDidLayoutSubviews
{
    [super viewDidLayoutSubviews];

    [self updateLabelPreferredMaxLayoutWidthToCurrentWidth:self.label1];
    [self updateLabelPreferredMaxLayoutWidthToCurrentWidth:self.label2];
    [self updateLabelPreferredMaxLayoutWidthToCurrentWidth:self.label3];

    [self.view layoutSubviews];
}

Многострочные метки выставляют одну из недостатков автоматической компоновки. Мы должны обновить preferredMaxLayoutWidth, чтобы заставить ярлык переплавить и отрегулировать его высоту, иначе, если изображение будет изменено или повернуто, автоматическая компоновка не понимает, что метка должна быть оплачена и изменена.

Ответ 2

Если вы все еще хотите использовать автоматическое ограничение компоновки для своей метки. Это решение:

[self.lblBadgeValue sizeToFit];
self.constraintWidthBadgeLabel.constant =  self.lblBadgeValue.frame.size.width;
[self.lblBadgeValue needsUpdateConstraints];
[self.lblBadgeValue layoutIfNeeded];
  • Объясните больше:
  • sizeToFit → сделать высоту ярлыка, ширину с его содержание.
  • Итак, во время выполнения вам нужно обновить высоту ограничения, или ширину для метки
  • После этого вам нужно сказать для компилятора что требуется ограничение на обновление.
  • И в итоге вам нужно позвонить макет, если есть изменения в ограничении.

Ответ 3

Это тоже работает. https://github.com/jszumski/auto-layout-table-cells/blob/master/DynamicCellHeights/JSLabel.m

@interface JSLabel : UILabel

@end

@implementation JSLabel

- (id)init {
    self = [super init];

    // required to prevent Auto Layout from compressing the label (by 1 point usually) for certain constraint solutions
    [self setContentCompressionResistancePriority:UILayoutPriorityRequired
                                          forAxis:UILayoutConstraintAxisVertical];

    return self;
}

- (void)layoutSubviews {
    [super layoutSubviews];

    self.preferredMaxLayoutWidth = CGRectGetWidth(self.bounds);

    [super layoutSubviews];
}

@end