Подтвердить что ты не робот

Возможно ли прокручивать UIStackView?

Скажем, я добавил больше просмотров в UIStackView, которые могут отображаться, как я могу сделать прокрутку UIStackView?

4b9b3361

Ответ 1

На случай, если кто-то ищет решение без кода, я создал пример, чтобы сделать это полностью в раскадровке, используя Auto Layout.

Вы можете получить его из github.

В основном, чтобы воссоздать пример:

  1. Создайте UIScrollView и установите его ограничения.
  2. Добавьте UIStackView к UIScrollView
  3. Установите ограничения: Leading, Trailing, Top & Bottom должен совпадать с UIScrollView
  4. Установите равный Width (вертикальный UIStackView) или Height (для горизонтального UIStackView) ограничение между UIStackView и UIScrollView.
  5. Установите ось = вертикальная/горизонтальная, выравнивание = заливка, распределение = равный интервал и интервал = 0 на UIStackView
  6. Добавьте номер UIViews к UIStackView
  7. Бегать

Ответ 2

Руководство по автоматической компоновке Apple включает в себя весь раздел Работа со списками прокрутки. Некоторые соответствующие фрагменты:

  1. Соедините представления содержимого сверху, снизу, переднего и заднего краев с прокручивающимися представлениями соответствующих ребер. Теперь представление содержимого определяет область содержимого прокрутки.
  2. (Необязательно) Чтобы отключить горизонтальную прокрутку, установите ширину просмотров содержимого равной ширине прокрутки. Теперь представление содержимого заполняет Просмотр прокрутки по горизонтали.
  3. (Необязательно) Чтобы отключить вертикальную прокрутку, установите высоту представлений контента, равную высоте просмотров прокрутки. Просмотр содержимого теперь заполняется вид прокрутки по горизонтали.

Далее

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

Подводя итог, представление содержимого прокрутки (в данном случае, представление стека) должно быть привязано к его краям и иметь ограничения по ширине и/или высоте. Это означает, что содержимое представления стека должно быть ограничено (прямо или косвенно) в направлении (направлениях), в котором требуется прокрутка, что может означать, например, добавление ограничения высоты для каждого представления в виде вертикального прокручивания стека. Ниже приведен пример того, как разрешить вертикальную прокрутку вида прокрутки, содержащего представление стека:

// Pin the edges of the stack view to the edges of the scroll view that contains it
stackView.topAnchor.constraintEqualToAnchor(scrollView.topAnchor).active = true
stackView.leadingAnchor.constraintEqualToAnchor(scrollView.leadingAnchor).active = true
stackView.trailingAnchor.constraintEqualToAnchor(scrollView.trailingAnchor).active = true
stackView.bottomAnchor.constraintEqualToAnchor(scrollView.bottomAnchor).active = true

// Set the width of the stack view to the width of the scroll view for vertical scrolling
stackView.widthAnchor.constraintEqualToAnchor(scrollView.widthAnchor).active = true

Ответ 3

Как говорит Эйк, UIStackView и UIScrollView прекрасно играют вместе, см. здесь.

Ключевым моментом является то, что UIStackView обрабатывает переменную высоту/ширину для различного содержимого, а затем UIScrollView хорошо выполняет свою работу по прокрутке/отскоку этого содержимого:

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    scrollView.contentSize = CGSize(width: stackView.frame.width, height: stackView.frame.height)       
}

Ответ 4

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

Я сделал два вопроса, хотя другие должны знать:

  • После добавления ограничений, аналогичных тем, которые включены в принятом ответе, я получаю красную ошибку автоопределения Need constraints for: X position or width. Это было решено путем добавления UILabel в качестве подвид представления стека.

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

  • Я изначально попытался добавить UIButtons в UIStackView. Будут загружены кнопки и представления, но прокрутка не будет прокручиваться. Это было решено, добавив UILabels в Stack View вместо кнопок. Используя те же ограничения, эта иерархия представлений с прокруткой UILabels, но UIButtons не делает.

    Я смущен этой проблемой, поскольку UIButtons действительно имеют IntrinsicContentSize (используется Stack View). Если кто-нибудь знает, почему кнопки не работают, я хотел бы знать, почему.

Вот моя иерархия и ограничения для ссылки:

constraints for stack view in scroll view[1]

Ответ 5

Я хотел сделать то же самое и наткнулся на эту Если вы хотите сделать это программно, используя API-интерфейс anchor, это это путь.

Подводя итог, вставьте UIStackView в UIScrollView и установите ограничения привязки UIStackView в соответствии с параметрами UIScrollView:

stackView.leadingAnchor.constraintEqualToAnchor(scrollView.leadingAnchor).active = true
stackView.trailingAnchor.constraintEqualToAnchor(scrollView.trailingAnchor).active = true
stackView.bottomAnchor.constraintEqualToAnchor(scrollView.bottomAnchor).active = true
stackView.topAnchor.constraintEqualToAnchor(scrollView.topAnchor).active = true
stackView.widthAnchor.constraintEqualToAnchor(scrollView.widthAnchor).active = true

Ответ 6

До 2019 года.

100% раскадровка ИЛИ 100% код.


Вот самое простое объяснение:

  1. Пустая полноэкранная сцена

  2. Добавить вид прокрутки. Удерживая клавишу Control, перетащите из вида прокрутки в базовый вид, добавьте слева направо, сверху вниз, все ноль.

  3. Добавьте представление стека в представлении прокрутки. Удерживая клавишу Control, перетащите из представления стека в представление прокрутки, добавьте левый-правый-верх-нижний, все ноль

  4. Поместите одну UILabel в представление стека.

Для ясности сделайте цвет фона красным; установите высоту 100, и в вашем представлении стека установите интервал до 20.

  1. Теперь установите ширину UILabel:

    Удивительно, перетаскивая управление от UILabel к представлению прокрутки, не представлению стека, и выберите равные ширины.

Повторить:

Не управляйте перетаскиванием из UILabel в родительский UILabel - переходите к бабушке и дедушке. (Другими словами, перейдите полностью к представлению прокрутки, не переходите к представлению стека.)

Это так просто. Это секрет.

  1. Затем вы должны нажать на одну UILabel, и вы должны буквально нажать несколько раз на копировать-вставить. Он не будет работать только с одним элементом. (НЕ нажимайте "дублировать", нажмите "копировать, затем вставить".)

Вы сделали Это так просто.

Совет: попробуйте добавить новый элемент в представление стека, скажем, UIView (возможно, для использования в качестве пробела). Обратите внимание, что все идет не так. Фактически вы должны добавить высоту к каждому новому элементу (скажем, "100"). Каждый раз, когда вы добавляете новый элемент, вы должны каким-то образом указывать его высоту.


Еще один способ взглянуть на это:

Выше это говорит: неожиданно, установите ширину UILabels равной ширине представления прокрутки (не представления стека). Это работает отлично.

С другой стороны...

Обратите внимание, что представление стека влево и вправо прикреплено к его родителю, представлению прокрутки. Попробуй это:

Перетащите из представления стека в представление прокрутки и добавьте ограничение "ширина равна". Это кажется странным, потому что вы уже прикололись влево-вправо, но именно так вы это делаете. Как ни странно, кажется, что секрет.

Итак, у вас есть два варианта:

  1. Удивительно, но установите ширину UILabels равной ширине прародителя scrollview (а не родительского стека).

или же

  1. Удивительно, но задайте "ширину, равную" для стека, в виде скролла - даже если у вас все равно есть левый и правый края стека в виде скролла.

Чтобы было ясно, используйте ОДИН из этих методов, НЕ делайте оба.

Ответ 8

Горизонтальная прокрутка (UIStackView в UIScrollView)

Для горизонтальной прокрутки. Сначала создайте UIStackView и UIScrollView и добавьте их в представление следующим образом:

let scrollView = UIScrollView()
let stackView = UIStackView()

scrollView.addSubview(stackView)
view.addSubview(scrollView)

Не UIStackView установить для translatesAutoresizingMaskIntoConstraints значение false в UIStackView и UIScrollView:

stackView.translatesAutoresizingMaskIntoConstraints = false
scrollView.translatesAutoresizingMaskIntoConstraints = false

Чтобы все работало, конечные, ведущие, верхние и нижние привязки UIStackView должны быть равны UIStackView UIScrollView:

stackView.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor).isActive = true
stackView.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor).isActive = true
stackView.topAnchor.constraint(equalTo: scrollView.topAnchor).isActive = true
stackView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor).isActive = true

Но ширина привязки UIStackView должна быть равна или больше ширины привязки UIScrollView:

stackView.widthAnchor.constraint(greaterThanOrEqualTo: scrollView.widthAnchor).isActive = true

Теперь прикрепите ваш UIScrollView, например:

scrollView.heightAnchor.constraint(equalToConstant: 80).isActive = true
scrollView.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true

scrollView.bottomAnchor.constraint(equalTo:view.safeAreaLayoutGuide.bottomAnchor).isActive = true
scrollView.leadingAnchor.constraint(equalTo:view.leadingAnchor).isActive = true
scrollView.trailingAnchor.constraint(equalTo:view.trailingAnchor).isActive = true 

Далее я бы предложил попробовать следующие настройки для выравнивания и распространения UIStackView:

topicStackView.axis = .horizontal
topicStackView.distribution = .equalCentering
topicStackView.alignment = .center

topicStackView.spacing = 10

Наконец, вам нужно использовать метод addArrangedSubview: для добавления подпредставлений в ваш UIStackView.

Текстовые вставки

Еще одна полезная функция, которая может оказаться полезной, заключается в том, что, поскольку UIStackView содержится в UIScrollView вас теперь есть доступ к текстовым вставкам, чтобы все выглядело немного красивее.

let inset:CGFloat = 20
scrollView.contentInset.left = inset
scrollView.contentInset.right = inset

// remember if you're using insets then reduce the width of your stack view to match
stackView.widthAnchor.constraint(greaterThanOrEqualTo: topicScrollView.widthAnchor, constant: -inset*2).isActive = true

Ответ 9

Вы можете попробовать ScrollableStackView: https://github.com/gurhub/ScrollableStackView

Это библиотека Objective-C и Swift. Он доступен через CocoaPods.

Пример кода (Swift)

import ScrollableStackView

var scrollable = ScrollableStackView(frame: view.frame)
view.addSubview(scrollable)

// add your views with 
let rectangle = UIView(frame: CGRect(x: 0, y: 0, width: 100, height: 55))
rectangle.backgroundColor = UIColor.blue
scrollable.stackView.addArrangedSubview(rectangle)
// ...

Пример кода (Objective-C)

@import ScrollableStackView

ScrollableStackView *scrollable = [[ScrollableStackView alloc] initWithFrame:self.view.frame];
scrollable.stackView.distribution = UIStackViewDistributionFillProportionally;
scrollable.stackView.alignment = UIStackViewAlignmentCenter;
scrollable.stackView.axis = UILayoutConstraintAxisVertical;
[self.view addSubview:scrollable];

UIView *rectangle = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 55)];
[rectangle setBackgroundColor:[UIColor blueColor]];

// add your views with
[scrollable.stackView addArrangedSubview:rectangle]; 
// ...

Ответ 10

Если у вас есть ограничение, чтобы центрировать Stack View вертикально внутри прокрутки, просто удалите его.

Ответ 11

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

  • После этого сделайте свободную форму контроллера контроллера (выберите из атрибута   инспектор) и установить высоту и ширину согласно внутреннему контенту   размер вашего представления (выбирается из инспектора размера).

  • После этого в контроллере представления появится прокрутка, и это логики, которые, как я обнаружил, работают почти все время в iOS (может потребоваться пройти через документацию этого класса представления, которую можно получить с помощью команды + щелкнуть по этому классу или через googling)

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

Во время работы с представлением стека

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

  • После этого настройте свойство представления стека. Если желаемый вид еще не достигнут, используйте другой вид стека.

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

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

Ответ 12

Пример для вертикального просмотра стека/прокрутки (с помощью EasyPeasy для автоотключения):

let scrollView = UIScrollView()
self.view.addSubview(scrollView)
scrollView <- [
    Edges(),
    Width().like(self.view)
]

let stackView = UIStackView(arrangedSubviews: yourSubviews)
stackView.axis = .vertical
stackView.distribution = .fill    
stackView.spacing = 10
scrollView.addSubview(stackView)
stackView <- [
    Edges(),
    Width().like(self.view)
]

Просто убедитесь, что определена каждая высота вашего подвидности!

Ответ 13

Для вложенного или одиночного стекового вида прокрутки необходимо установить фиксированную ширину с корневым представлением. Основной вид стека, который находится внутри вида прокрутки, должен иметь одинаковую ширину. [Мой вид прокрутки ниже представления игнорировать его]

Установите равное ограничение ширины между UIStackView и UIScrollView.

enter image description here

Ответ 14

Если кто-то ищет горизонтально прокрутки

func createHorizontalStackViewsWithScroll() {

 self.view.addSubview(stackScrollView)
 stackScrollView.translatesAutoresizingMaskIntoConstraints = false
 stackScrollView.heightAnchor.constraint(equalToConstant: 85).isActive = true
 stackScrollView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor).isActive = true
 stackScrollView.trailingAnchor.constraint(equalTo: self.view.trailingAnchor).isActive = true
 stackScrollView.bottomAnchor.constraint(equalTo: visualEffectViews.topAnchor).isActive = true
 stackScrollView.addSubview(stackView)

 stackView.translatesAutoresizingMaskIntoConstraints = false
 stackView.topAnchor.constraint(equalTo: stackScrollView.topAnchor).isActive = true
 stackView.leadingAnchor.constraint(equalTo: stackScrollView.leadingAnchor).isActive = true
 stackView.trailingAnchor.constraint(equalTo: stackScrollView.trailingAnchor).isActive = true
 stackView.bottomAnchor.constraint(equalTo: stackScrollView.bottomAnchor).isActive = true
 stackView.heightAnchor.constraint(equalTo: stackScrollView.heightAnchor).isActive = true

 stackView.distribution = .equalSpacing
 stackView.spacing = 5
 stackView.axis = .horizontal
 stackView.alignment = .fill


 for i in 0 ..< images.count {
 let photoView = UIButton.init(frame: CGRect(x: 0, y: 0, width: 85, height: 85))
 // set button image
 photoView.translatesAutoresizingMaskIntoConstraints = false
 photoView.heightAnchor.constraint(equalToConstant: photoView.frame.height).isActive = true
 photoView.widthAnchor.constraint(equalToConstant: photoView.frame.width).isActive = true

 stackView.addArrangedSubview(photoView)
 }
 stackView.setNeedsLayout()

 }

Ответ 15

Поместите вид прокрутки на вашу сцену и измените его размер так, чтобы он заполнил всю сцену. Затем поместите представление стека в представление прокрутки и поместите кнопку добавления элемента в представление стека. Как только все будет готово, установите следующие ограничения:

Scroll View.Leading = Superview.LeadingMargin
Scroll View.Trailing = Superview.TrailingMargin
Scroll View.Top = Superview.TopMargin
Bottom Layout Guide.Top = Scroll View.Bottom + 20.0
Stack View.Leading = Scroll View.Leading
Stack View.Trailing = Scroll View.Trailing
Stack View.Top = Scroll View.Top
Stack View.Bottom = Scroll View.Bottom
Stack View.Width = Scroll View.Width

enter image description here

Код: Stack View.Width = Scroll View.Width является ключом.

Ответ 16

Поместите его в UIScrollView...