Как добавить начальный отступ для просмотра, добавленного внутри 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)...

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. Затем установите ограничение ширины этих невидимых дочерних элементов, чтобы настроить отступы.


-3

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

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

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

stackView.leadingAnchor.constraintEqualToAnchor(selectedContactsScrollView.leadingAnchor, constant: 15).active = true

1
на самом деле ваш код добавляет начало для uistackview внутри urscrollview, он не добавляет отступ для ваших представлений внутри вашего uistackview (как указано в вопросе)
Уильям Кинаан

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

На первый взгляд, вы можете использовать другой uistackview в своем исходном uistackview и добавить к нему отступы. затем добавьте свои представления в этот новый uistackview (вы можете сделать это полностью с помощью конструктора интерфейсов, нет необходимости писать для него код)
Уильям Кинаан

Да, это сработает. Вы можете добавить в качестве ответа, и я приму это.
Адриан
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.