iOS: многострочный UILabel в автоматической компоновке



У меня возникли проблемы с попыткой добиться очень простого поведения макета с автоматической компоновкой. Мой контроллер вида выглядит так В IB:



enter image description here



верхняя метка-это метка заголовка, я не знаю, сколько строк это будет. Мне нужна метка заголовка для отображения всех строк текста. Мне также нужны две другие этикетки и маленькое изображение, которое будет выложено прямо под заголовком, каким бы высоким оно ни было. Я установил ограничения по вертикальному расстоянию между метками и маленькое изображение, а также ограничение верхнего интервала между меткой заголовка и ее супервизором и ограничение Нижнего интервала между маленьким изображением и его супервизором. Белый UIView не имеет ограничения по высоте, поэтому он должен растягиваться вертикально, чтобы содержать его подвиды. Я установил количество строк для метки заголовка в 0.



Как я могу изменить размер метки заголовка, чтобы соответствовать количеству строк, требуемых строкой? Я понимаю, что я не могу использовать методы setFrame, потому что я использование автоматической компоновки. И я должен использовать Auto Layout, потому что мне нужны эти другие представления, чтобы оставаться ниже метки заголовка (следовательно, ограничения).



Как я могу это сделать?

661   8  

8 ответов:

использовать -setPreferredMaxLayoutWidth на UILabel и autolayout должен обрабатывать все остальное.

[label setPreferredMaxLayoutWidth:200.0];

посмотреть документация UILabel.

обновление:

только нужно установить ограничение высоты в раскадровке больше или равно", не нужно setPreferredMaxLayoutWidth.

разверните свой набор меток количество строк до 0, а также, что более важно, для автоматической компоновки установите высоту >= x. Auto layout сделает все остальное. Вы также можете содержать другие элементы, основанные на предыдущем элементе, чтобы правильно позиционировать их.

auto layout

Источник:http://www.objc.io/issue-3/advanced-auto-layout-toolbox.html

внутренний размер содержимого многострочного текста

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

поскольку мы обычно не знаем это значение заранее, нам нужно принять двухэтапный подход, чтобы получить это право. Сначала мы позволяем Auto Layout делать свою работу, а затем мы используем полученный кадр в проходе макета, чтобы обновить предпочтительную максимальную ширину и снова запустить макет.

- (void)layoutSubviews
{
    [super layoutSubviews];
    myLabel.preferredMaxLayoutWidth = myLabel.frame.size.width;
    [super layoutSubviews];
}

первый вызов [super layoutSubviews] необходим для того, чтобы метка получила свой набор кадров, в то время как второй вызов необходимо обновить макет после изменения. Если мы опустим второй вызов, мы получим ошибку NSInternalInconsistencyException, потому что мы внесли изменения в проход макета, которые требуют обновления ограничений, но мы не запускали макет снова.

мы также можем сделать это в ярлык сам подкласс:

@implementation MyLabel
- (void)layoutSubviews
{
    self.preferredMaxLayoutWidth = self.frame.size.width;
    [super layoutSubviews];
}
@end

в этом случае нам не нужно сначала вызывать [super layoutSubviews], потому что когда layoutSubviews вызывается, у нас уже есть рамка на метке себя.

чтобы сделать эту настройку с уровня контроллера вида, мы подключаемся к viewDidLayoutSubviews. На этом этапе рамки первого этапа автоматической компоновки уже установлены, и мы можем использовать их для установки предпочтительной максимальной ширины.

- (void)viewDidLayoutSubviews
{
    [super viewDidLayoutSubviews];
    myLabel.preferredMaxLayoutWidth = myLabel.frame.size.width;
    [self.view layoutIfNeeded];
}

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

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

вот ключ: Interface Builder любит бросать дополнительные ограничения при добавлении и перемещении представлений, и вы можете не заметить. В моем случае у меня был вид на полпути вниз, который имел дополнительное ограничение, которое указывало размер между ним и его супервизором, в основном привязывая его к этой точке. Это означало: что ничто выше этого не может изменить размер больше, потому что это будет идти против этого ограничения.

простой способ сказать, если это так, пытаясь изменить размер метки вручную. ИБ позволяет тебе его выращивать? Если да, то перемещаются ли метки ниже, как вы ожидаете? Убедитесь, что вы оба из них проверены перед изменением размера, чтобы увидеть, как ваши ограничения будут перемещать ваши представления:

IB Menu

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

Я считаю, что вам нужно следующее:

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

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

Я нашел способ сделать это :

после того, как вы установили ограничения на свою метку и установили ее многострочное свойство в 0, создайте подкласс UILabel ; я назвал мой AutoLayoutLabel:

@implementation AutoLayoutLabel

- (void)layoutSubviews{
    [self setNeedsUpdateConstraints];
    [super layoutSubviews];
    self.preferredMaxLayoutWidth = CGRectGetWidth(self.bounds);
}

@end

у меня есть UITableViewCell, который имеет метку переноса текста. Я работал с переносом текста следующим образом.

1) установите ограничения UILabel следующим образом.

enter image description here

2) установить нет. линий до 0.

3) добавлено ограничение высоты UILabel для UITableViewCell.

@IBOutlet weak var priorityLabelWidth: NSLayoutConstraint!

4) На UITableViewCell:

priorityLabel.sizeToFit()
priorityLabelWidth.constant = priorityLabel.intrinsicContentSize().width+5

один из способов сделать это... По мере увеличения длины текста попробуйте изменить (уменьшить) размер шрифта текста метки с помощью

Label.adjustsFontSizeToFitWidth = YES;

Comments

    Ничего не найдено.