Минимальная и максимальная высота UIView с автоматической компоновкой

У меня есть представление, которое правильно отображается на экране iPhone 6, но требует прокрутки на экране iPhone 5. Я пытаюсь изменить некоторые ограничения Auto Layout, чтобы избавиться от необходимости прокручивать последнее.

Вот попытка наглядно объяснить мою ситуацию:  введите описание изображения здесь

Первые 2 скриншота - это существующие ситуации на iPhone 6 и iPhone 5. Третий - это то, чего я пытаюсь достичь (только на iPhone 5).

Я написал следующие ограничения Auto Layout, но мне кое-что не хватает:


[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-(>=25,<=50)-[blueView]-(>=25,<=50)-[redView]-5-|"
                                                             options:0
                                                             metrics:nil
                                                               views:nameMap]];

Следует ли здесь задействовать сопротивление объятиям и / или сжатию? В каком смысле?


Измените, чтобы показать больше моего фактического кода:

[self addSubview:loginNSignupScrollView];
[self.loginNSignupScrollView addSubview:logoImageView];
[self.loginNSignupScrollView addSubview:horizontalScrollView];
[self.loginNSignupScrollView addSubview:appVersionLabel];
[self.horizontalScrollView addSubview:loginView];

[self addConstraints: [NSLayoutConstraint constraintsWithVisualFormat: @ "V: | [loginNSignupScrollView] |" варианты: 0 метрики: ноль просмотров: nameMap]];

[self addConstraints: [NSLayoutConstraint constraintsWithVisualFormat: @ "V: | [loginView (== 350)]" параметры: 0 метрик: ноль просмотров: nameMap]];

[self addConstraints: [NSLayoutConstraint constraintsWithVisualFormat: @ "V: | - (> = 30,‹ = 60) - [logoImageView (== 35)] - (> = 25, ‹= 50) - [horizontalScrollView] -30- [ appVersionLabel] -5- | " варианты: 0 метрики: ноль просмотров: nameMap]];

[self addConstraint: [NSLayoutConstraint constraintWithItem: атрибут self.horizontalScrollView: NSLayoutAttributeHeight relatedBy: NSLayoutRelationEqual toItem: self атрибут: NSLayoutAttributeHeight multiplier: 0,0 константа: 350]];


person Pierre Espenan    schedule 13.11.2015    source источник
comment
Есть ли у вас другие ограничения, которые вы не показали? - Получаете ли вы сообщения в консоли?   -  person matt    schedule 13.11.2015
comment
@matt, пожалуйста, посмотрите мою правку. Я не получаю никаких жалоб от движка Auto Layout в консоли.   -  person Pierre Espenan    schedule 13.11.2015
comment
Ах. Итак, все это происходит в режиме прокрутки. Вы знаете, как автоматический макет работает с представлениями внутри представлений прокрутки? Это работает совершенно особенным образом. Вы знаете об этом? Кроме того, что это за дополнительные просмотры? Их нет на ваших снимках экрана. А где ваши горизонтальные ограничения? И как позиционируется само представление прокрутки?   -  person matt    schedule 13.11.2015
comment
Я изо всех сил старался упростить свой случай до необходимого минимума. Может быть, я слишком упростил это. О поведении Auto Layout в просмотре прокрутки: я знаю об этом, но не думал, что это может быть проблемой здесь. Ммм, дай мне взглянуть. Сам scrollview позиционируется с помощью @"H:|[loginNSignupScrollView]|" и @"V:|[loginNSignupScrollView]|"   -  person Pierre Espenan    schedule 13.11.2015


Ответы (2)


Как вы знаете, представления с прокруткой являются особенными, потому что, если вы используете внутри них автоматический макет, размер содержимого (размер прокручиваемого содержимого) определяется ограничениями изнутри. Таким образом, вы не можете напрямую делать то, что пытаетесь сделать. Лучшая стратегия:

  • Представление прокрутки, прикрепленное к супервизору (главному представлению)

  • Пустое представление содержимого внутри представления прокрутки, прикрепленное к представлению прокрутки с нулевыми константами

  • Все остальное в представлении содержимого

После того, как вы это настроите, произойдут две хорошие вещи:

  • Размер представления содержимого равен contentSize представления прокрутки. Так что все, что вам нужно сделать, это указать это явно. Разумным подходом может быть установка его в коде viewDidLayoutSubviews; это самое раннее известное значение истинного окончательного размера интерфейса.

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

Используя такую ​​стратегию, я добился этого (симуляторы 4 и 6 соответственно), что, по крайней мере, похоже на то, что вам нужно; обратите внимание, что мы действительно находимся в режиме прокрутки, хотя вы не можете сказать по снимкам экрана:

введите здесь описание изображения

введите здесь описание изображения

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

Единственный код, который я использовал, - это установить размер представления содержимого, который (как я уже сказал) совпадает с установкой contentSize представления прокрутки:

NSLayoutConstraint.activateConstraints([
    self.contentView.widthAnchor.constraintEqualToConstant(
        self.view.bounds.size.width),
    self.contentView.heightAnchor.constraintEqualToConstant(
        self.view.bounds.size.height),
])
person matt    schedule 13.11.2015
comment
Это действительно, вероятно, лучший подход здесь. Я попробую это попробовать. Что вы имеете в виду под нулевыми константами? - person Pierre Espenan; 13.11.2015
comment
Ограничения имеют constant свойства. Ваш собственный код содержит пример. - person matt; 13.11.2015
comment
Ах да, я сутулый. - person Pierre Espenan; 13.11.2015
comment
Обновил свой ответ снимками экрана, показывающими, что эта стратегия, вероятно, сработает для вас. - person matt; 13.11.2015
comment
Не могли бы вы поделиться своим кодом? Я все еще не могу позволить пустым пространствам увеличиваться / уменьшаться. При использовании V:|-(>=30,<=100)-[logoImageView(==35)]-(>=25,<=100)-[horizontalView(==350)]| размер пустого пространства всегда устанавливается на минимально возможные значения (30 и 25). - person Pierre Espenan; 16.11.2015
comment
Возможно, я неправильно понял проблему. Я думал, что проблема заключалась в том, чтобы нижняя часть нижнего представления (ваш красный вид) находилась внутри окна. Итак, мой единственный код - предоставить ограничения, которые устанавливают размер представления содержимого; Я добавил этот код к своему ответу. - person matt; 16.11.2015
comment
Как я объяснил в своем ответе, я не был полностью уверен, что вам нужно (предложенные вами ограничения не имели для меня смысла), поэтому я просто ограничил пробелы, чтобы они были равны, таким образом расположив синий вид красиво между верхней частью экрана и верхней части красного представления, при этом высота красного представления (и синего представления) остается постоянной. В своем ответе я признал, что это может быть не совсем то, что вы хотели. - person matt; 16.11.2015
comment
Ах, общение затруднено :) Тем не менее, позвольте мне взглянуть на ваш обновленный ответ. Возможно, это то, что я пытаюсь сделать. - person Pierre Espenan; 16.11.2015

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

person Abhishek    schedule 13.11.2015