Как добавить начальный отступ для просмотра, добавленного внутри UIStackView

127

Это моя установка: у меня есть UIScrollViewведущая, верхняя, пробная кромка, установленная на 0. Внутри нее я добавляю UIStackViewследующие ограничения:

stackView.centerYAnchor.constraintEqualToAnchor(selectedContactsScrollView.centerYAnchor).active = true  
stackView.leadingAnchor.constraintEqualToAnchor(selectedContactsScrollView.leadingAnchor).active = true

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

Как я могу добавить отступ к первому представлению? Без настройки ограничений просмотра прокрутки.

Адриан
источник
2
не могли бы вы изменить принятый ответ? Ответ Толги кажется намного лучше.
Дорогая,

Ответы:

27

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

Решением может быть добавление еще одного UIStackView в исходный UIStackView и переход к новому UIStackVIew. Затем добавьте свои представления в этот новый UIStackView.

Подсказка, вы можете сделать это полностью с помощью Interface Builder. Другими словами, для этого не нужно писать код.

Уильям Кинаан
источник
375

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

stackView.layoutMargins = UIEdgeInsets(top: 0, left: 20, bottom: 0, right: 20)
stackView.isLayoutMarginsRelativeArrangement = true

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

Толга Окур
источник
2
isLayoutMarginsRelativeArrangementэто геттер, сеттер layoutMarginsRelativeArrangement. Я не могу отредактировать ответ
Маросс
5
@maross в Swift нет разницы между функцией получения и установки. Но вы правы, люди, которые разрабатывают с Objective-C, должны использовать layoutMarginsRelativeArrangementвместо него. Официальная документация: developer.apple.com/reference/uikit/uistackview/…
Толга Окур
3
Для Objective-C:stackView.layoutMargins = UIEdgeInsetsMake(0, 20, 0, 20); [stackView setLayoutMarginsRelativeArrangement:YES];
Snouto
4
Февраль 2019, полночь, сижу в офисе - подобные ответы дают мне силы двигаться дальше. Спасибо @tolpp
nefarianblack
156

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

(Например, если я добавляю ведущее / конечное ограничение к выбранному в представлении стека изображений, которое также добавляет ведущее к представлению коллекции, но не добавляет конечного; и это наверняка будет конфликтом).

stackview внутри stackview

Чтобы установить поля макета для всех видов в стеке, выберите:

Stack View > Size Inspector > Layout Margins > Fixed

Примечание: "Fixed"опция раньше вызывалась "Explicit", как видно на скриншотах.

Затем добавьте отступ:

раскадровка

Запорожченко Александр
источник
23
одна из вещей, которые скрывает Apple. Я ненавижу то, что Xcode - это полная противоположность хорошему, дружелюбному и простому. Спасибо
Duck
Xcode продолжает сбой, когда я изменяю эти явные поля макета. Сообщил об ошибке, но они ответили, что это дубликат.
mvandillen 03
Этого я не нашел в пользовательском интерфейсе. Измените поля макета на явные, чтобы увидеть поля для полей просмотра стека.
pkamb
13
FYI XCode 9 теперь называет это «фиксированным», а не «явным».
Мел
Также в Xcode 9 снимите флажок «Использовать руководства по макету безопасных областей» в инспекторе файлов, который на момент написания все еще вызывает множество проблем в IB, и придерживайтесь обычных руководств по макету для ваших ограничений.
PJ_Finnegan
16

Что сработало для меня, так это добавить в представление стека еще один UIView, который просто разделитель (работает по крайней мере с stackView.distribution = .Fill):

let spacerView = UIView(frame: CGRect(x: 0, y: 0, width: 10, height: 10))
stackView.addArrangedSubview(spacerView)
stackView.addArrangedSubview(viewThatNeedsSpaceBeforeIt)
stackView.addArrangedSubview(NextView)...
dorsz
источник
6

swift 3: вам просто нужно установить смещение:

firstView.leadingAnchor.constraint(equalTo: parentView.leadingAnchor, constant: 200).isActive = true

Убедитесь, что это ограничение установлено после того, как вы parentView.addArrangdSubView(firstView)

Уильям Ху
источник
4

Если вам нужно только начальное заполнение, то вы можете установить для параметра «Выравнивание» представления стека значение «Конечный», и тогда вы сможете указать уникальные ограничения начального уровня для каждого из содержащихся в нем подвидов.

В качестве бонуса вы также можете установить выравнивание представления стека на «Центр», а затем вы можете использовать ограничения Leading и / или Trailing, чтобы дать каждому элементу собственное заполнение с обеих сторон.

Джонатан Пархэм
источник
1

На этот вопрос уже есть хорошие ответы. Одно предложение: используйте spacingсвойство, чтобы установить интервал между представлениями. Для первого и последнего представлений может быть два варианта: либо установить вставки, как предлагается @tolpp, либо добавить ограничение, прикрепляемое к родительскому (stackview) с константой, чтобы добавить отступ.

бесконечный цикл
источник
1

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

Это можно сделать в построителе интерфейсов и программно.

Эйден Диксон
источник
0

Что мы сделали, так это добавили прозрачные компоненты (например, UIButton / UIView) в качестве первого и последнего потомков UIStackView. Затем установите ограничение ширины этих невидимых дочерних элементов, чтобы настроить отступы.

Crashalot
источник
-3

Кажется, решение было довольно простым. Вместо того:

stackView.leadingAnchor.constraintEqualToAnchor(selectedContactsScrollView.leadingAnchor).active = true

Я просто написал:

stackView.leadingAnchor.constraintEqualToAnchor(selectedContactsScrollView.leadingAnchor, constant: 15).active = true
Адриан
источник
1
на самом деле ваш код добавляет начало для uistackview внутри urscrollview, он не добавляет отступ для ваших представлений внутри вашего uistackview (как указано в вопросе)
Уильям Кинаан
да, но я не знаю, можно ли добавить отступы, так что это сработает для меня.
Адриан
На первый взгляд, вы можете использовать другой uistackview в своем исходном uistackview и добавить к нему отступы. затем добавьте свои представления в этот новый uistackview (вы можете сделать это полностью с помощью конструктора интерфейсов, нет необходимости писать для него код)
Уильям Кинаан
Да, это сработает. Вы можете добавить в качестве ответа, и я приму это.
Адриан