изменение размера супервизора после динамического изменения подвидов с помощью автозапуска


я не могу из любви к Богу повесить это изменение размера супервизора.

у меня есть UIView *superview с 4 UILabels. 2 функции в качестве заголовка для 2 других.

содержание во всех 4 динамические исходящие из базы данных.

SizeToFit vs SizeThatFits:(CGSize) vs UIView systemLayoutSizeFittingSize:, проходящего либо UILayoutFittingCompressedSize или UILayoutFittingExpandedSize.

я использую autolayout программно и установил высоту супервизора равной или больше фиктивного числа.

где и как я могу использовать эти SizeToFit vs sizeThatFits:(CGSize) vs UIView systemLayoutSizeFittingSize:, проходящего либо UILayoutFittingCompressedSize или UILayoutFittingExpandedSize. Я прочитал много советов здесь на стеке, но в конечном итоге ничего.

мне нужно пересчитать ограничения для супервизора где-то конкретно. Maby установка высоты, чтобы быть @property` в своем классе контроллера и удалить и прочитать его? Банкомат я попытался положить все везде, а затем некоторые. Тем не менее я получаю тот же конечный результат размера с фиктивной высотой и текстом, плавающим снаружи. Даже после установки clipsToBound на подвиде.

я чешу волосы.. помогите

4 80

4 ответа:

если вы используете авто макет, вот что вам нужно сделать:

  1. убедитесь, что вы не добавляете фиксированные ограничения ширины и/или высоты к любому из ваших подвидов (в зависимости от того, какие размеры вы хотите динамически изменять). Идея состоит в том, чтобы позволить внутреннему размеру содержимого каждого подвида определять высоту подвида. UILabels поставляются с 4 автоматическими неявными ограничениями, которые будут (с меньшим, чем требуется приоритетом) пытаться сохранить рамку метки в точном размер, необходимый для размещения всего текста внутри.

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

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

вот и все. Вам не нужно звонить sizeToFit или systemLayoutSizeFittingSize: чтобы заставить это работать, просто загрузите свои представления и установите текст, и это должно быть так. Система компоновки двигателя будет делать расчеты для вы должны решить свои ограничения. (Во всяком случае, вам может понадобиться позвонить setNeedsLayout на суперпанель...но это не должно быть обязательным.)

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

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

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

H:|-(15.0)-[image(30.0)]-(15.0)-[label]-(15.0)-|
V:|[image(30.0)]|
V:|[label(>=30.0)]|

затем установите содержащее представление в соответствии с высотой метки. Теперь содержащий вид будет ездить размер этикетка.

как указал @smileyborg в своем ответе, соединение содержимого жестко с супервизором сообщает движку макета, что простое представление контейнера должно привести к его росту.

желтые прямоугольники выравнивания

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

UILabel that is multi-line

это было значительно проще с введением представлений стека в iOS 9. Используйте представление стека внутри вашего представления, чтобы содержать все ваше содержимое, которое изменяется, а затем просто вызовите

view.setNeedsUpdateConstraints()
view.updateConstraintsIfNeeded()
view.setNeedsLayout()
view.layoutIfNeeded()

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

view.systemLayoutSizeFittingSize(UILayoutFittingCompressedSize)

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

это почти следует за ответом @smileyborg и поставляется с конкретным примером.

enter image description here

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

  1. [Label] метки не должны иметь фиксированного height ограничение, в этом случае AutoLayout не будет изменять размер меток, чтобы соответствовать тексту, поэтому установка ограничений края является ключом. (зеленые стрелки)
  2. [Subview] шаги 1 и 3 очень легко следовать, но этот шаг может быть неправильно понят. Как и в случае с метками, подвиды не должны иметь height установить ограничение. Все подвиды должны иметь top множество ограничений, игнорируя bottom ограничение, которое может заставить вас думать, что вызовет неудовлетворенное исключение ограничения во время выполнения, но это не будет, если вы установите bottom ограничение для последнего подвида. Отсутствие для этого будет взорвать макет. (красный стрелки)

  3. [Superview] установите все ограничения так, как вам нужно, но обратите большое внимание на height ограничения. Назначьте ему случайное значение, но сделайте его необязательным, AutoLayout установит высоту точно в соответствии с подвидами. (синие стрелки)

это работает отлично, нет необходимости вызывать какие-либо дополнительные методы обновления макета системы.