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

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

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

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

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

 Badal Shah26 апр. 2016 г., 12:58
проверьте это, вам не нужно добавлять одну строку кодаstackoverflow.com/a/36862795/4910767
 Aniruddha25 авг. 2014 г., 11:25
Достигли ли вы требуемого результата?
 jemmons01 мая 2014 г., 00:19
Пожалуйста, рассмотрите маркировку @mwhuss 'ответ как принятый.
 jbandi23 дек. 2012 г., 13:35
Я также борюсь с подобной проблемой. Но я все еще изо всех сил пытаюсь заставить верхнюю метку динамически регулировать свою высоту, чтобы соответствовать содержанию. Как ты этого добился?

Ответы на вопрос(8)

попытайтесь изменить (уменьшить) размер шрифта текста надписи, используя

Label.adjustsFontSizeToFitWidth = YES;
 James Harpe09 окт. 2012 г., 14:22
Я хочу, чтобы различные экземпляры контроллера представления имели одинаковый внешний вид, поэтому я неЯ не хочу менять размер шрифта.
Решение Вопроса

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

[label setPreferredMaxLayoutWidth:200.0];

УвидетьUILabel документация.

ОБНОВИТЬ:

Нужно только установить ограничение высоты в раскадровке на значение «Больше или равно»Нет необходимости устанавливать setPreferredMaxLayoutWidth.

 ZigDanis23 окт. 2014 г., 14:01
@SjoerdPerfors!Скриншот.
 Sjoerd Perfors05 дек. 2013 г., 17:45
Хороший, в любом случае, чтобы сделать это в конструкторе интерфейсов?
 Olcay Ertaş05 мар. 2015 г., 12:55
Почему магия 200? Могу ли я использовать 300?
 Li Fumin03 февр. 2015 г., 09:17
Напоминание: пожалуйста, не забудьте установить свойство numberOfLines.
 jowie05 июн. 2014 г., 16:35
Также установите ограничение высоты в IB больше или равно ".
 Archagon11 дек. 2015 г., 10:39
Да. У меня была проблема, когда метки в моих ячейках возвращались к одной строке после того, как они исчезли с экрана, но не когда они появились впервые. Это исправило это прямо. Магия!
 MANIAK_dobrii08 февр. 2014 г., 18:02
@SjoerdPerfors выглядит так, как будто он использует текущую ширину для этого 'S значение, не уверен, если этоЭто всегда правда, но это было так для меня.
 mwhuss06 мар. 2015 г., 18:15
Да, используйте то, что вы хотите, чтобы максимальная ширина была.
 tboyce1209 окт. 2015 г., 02:46
Увидетьstackoverflow.com/a/29180323/1529675 как определитьpreferredMaxLayoutWidth и посмотретьdevetc.org/code/2014/07/07/auto-layout-and-views-that-wrap.html для краткой, но информативной рецензии, в комплекте с анимированными GIF-файлами (не моя рецензия, я нашел ее через Google)

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

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

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

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

 James Harpe26 нояб. 2012 г., 15:03
Да, после долгих тренировок я смог получить тот эффект, который хотел. Вы просто должны очень тщательно продумать ограничения, которые вы хотите. Это нене поможет, что IB постоянно бросает ограничения, которые вы не делаетене ожидаю.

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

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

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

@implementation AutoLayoutLabel

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

@end
 Massimo Polimeni16 июн. 2016 г., 14:41
Безразлично»не работает для меня :(

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

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

2) Установить № строк до 0.

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

@IBOutlet weak var priorityLabelWidth: NSLayoutConstraint!

4) На UITableViewCell:

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

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

 Tony25 мар. 2015 г., 19:28
Настройка автоматической максимальной ширины доступна только в iOS8. Кроме того, насколько я понимаю, он будет автоматически регулировать высоту, и, по моему опыту, вы неДля работы нужно установить ограничение по высоте. Это работало для меня, используя явную ширину.
 jmc10 февр. 2015 г., 21:54
Это нея не работаю с явно заданным предпочтительным значением максимальной ширины, поэтому убедитесь, что в IB этот параметр установлен автоматически. ура
 tboyce1209 окт. 2015 г., 02:49
Это нея не работаю я верюstackoverflow.com/a/13032251/1529675 это правильный ответ.
 Abolfoooud12 авг. 2015 г., 16:28
Я нашел это полезным в моей ситуации, но только если я установил приоритет сопротивления сжатию контента на 1000, чтобы он рос как я хотел
 Brainware26 янв. 2017 г., 21:39
Важный! Вы также должны ограничить ширину (конечный / начальный пробел или фактическая ширина). В противном случае, этикетка будет расти горизонтально и упаковка будет выиграна.т происходит.
 troppoli01 окт. 2015 г., 17:43
Было бы неплохо узнать, почему это работает, я боюсь, что это может быть "ошибка» что получает "фиксированный".
 bgolson19 нояб. 2014 г., 23:18
Это единственный ответ, который работал для меня в ячейке табличного представления. Также работает с фиксированным количеством строк (вместо 0 / без ограничений)
 Tom Howard02 сент. 2014 г., 17:18
Если этот метод нене работает для вас, пожалуйста, см. Кори Имдикеответ о том, что последующие взгляды неt Запретить Auto Layout изменять размеры (возможно) многострочного представления.

http://www.objc.io/issue-3/advanced-auto-layout-toolbox.html

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

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

Так как мы обычно неЧтобы знать это значение заранее, нам нужно сделать два шага, чтобы понять это правильно. Сначала мы позволяем 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. На этом этапе кадры первого прохода Auto Layout уже установлены, и мы можем использовать их для установки предпочтительной максимальной ширины.

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

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

 Anton Matosov05 мая 2015 г., 00:49
@ djibouti33 Можете ли вы предоставить минимальный пример кода (например, в формате github repo), чтобы я мог легко проверить вашу проблему?
 djibouti3320 апр. 2015 г., 23:51
спасибо, спасибо, спасибо не только за код, но, что более важно, за объяснение и примеры того, как это сделать не только в подклассе, но и из контроллера view.i '
 djibouti3305 мая 2015 г., 01:54
Спасибо @Антон. Наш дизайн с тех пор переключился с UITableView на UICollectionView, и, к счастью, я не видел этого поведения. Если я смогу воспользоваться своей историей Git для создания небольшого примера проекта, ядам тебе знать.
 naz06 нояб. 2015 г., 07:19
Проблема для меня, так как я начал работать на iOS 9, но когда я тестировал на iOS 8, проблема началась. Мне нужно установить максимальную ширину вручную.
 djibouti3321 апр. 2015 г., 00:11
Я пытаюсь это сделать в моем контроллере представления, и viewDidLayoutSubviews вызывается после viewWillAppear и viewDidAppear. После viewDidAppear, естьВспышка при правильном изменении размера меток. Есть ли способ избежать этого? Есть ли способ для изменения размера, прежде чем пользователь увидит что-нибудь? в моем случае мои многострочные метки находятся в tableHeaderView, и поэтому ям также изменяет размер представления заголовкаs высота на основе меток, использующих этот пример (stackoverflow.com/questions/20982558/...)

Верхнее ограничениеВедущее ограничение (например, левая сторона)Трейлинг-ограничение (например, правая сторона)Установите приоритет размещения контента, горизонтальный на низкий, так чтозаполню заданное место, если текст короткий.Установите сопротивление сжатию содержимого от горизонтального до низкого, так чтоОберну вместо того, чтобы попытаться стать шире.Установите количество строк в 0.Установите режим разрыва строки на перенос слов.
 user136626511 июл. 2017 г., 18:40
Это нерешить проблему.
 David Gay07 мар. 2018 г., 17:30
Приоритет объятия контента был моей проблемой. Спасибо, что сообщили мне об этом свойстве, а также о сопротивлении сжатию. Вы помогли мне решить многочасовую проблему.
 Anton Tropashko25 сент. 2017 г., 16:44
Это должно работать в xcode9. Мне не нужно было ничего делать с ограничением высоты метки (у меня его нет): в последнее время он работает только из коробки, как только метка будет ограничена (конечный, ведущий, верхний и нижний). Уикит делает все остальное

Ваш ответ на вопрос