Использование вида прокрутки с автозапуском Swift

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

При добавлении прокрутки я просматриваю следующие шаги:

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

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

  • Добавьте ограничение ширины между представлением содержимого и представлением контроллеров представления.

В этот момент я запустил приложение, просмотр содержимого не отображается, а прокрутка View занимает весь экран.

  1. Далее я добавляю элементы в представление содержимого, которые включают только 4 UIViews для тестирования всего. Я даю каждому верхнему, левому и правому ограничениям UIView. И последний UIView - нижнее ограничение.

Не в этот момент, когда я запускаю приложение, просмотр содержимого и просмотр прокрутки занимает примерно половину экрана, и я могу прокручивать представление содержимого. Смотрите фото внизу.

Я следил за каждым учебным пособием, которое я могу найти, и попытался реализовать все ответы SO, которые я нашел, но я не могу заставить его работать. Если кто-то встретил это или знает решение, ваша помощь будет очень оценена!

Зеленый - это вид содержимого, а синий - вид прокрутки

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

Параметры прокрутки и подсмотра

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

Ответ 1

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

  • Добавить представление прокрутки в виде подматрицы основного вида.

  • Выберите "Просмотр прокрутки" и снимите флажок "Ограничение на поля" и нажмите "Верх", "Влево", "Вправо", "Вниз", "Ограничения"

  • Добавьте UIView в качестве подзаголовка вида прокрутки. Назовите это представление "Просмотр содержимого"

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

  • Далее от представления содержимого к главному виду добавьте равные ширины и равные ограничения по высоте.

  • Добавьте все элементы, которые вам нужны в представлении содержимого. Свяжите верхние, левые, правые и высотные ограничения с добавленными элементами.

  • В самом низу в элементе содержимого в представлении содержимого указывается нижнее ограничение. Выберите это ограничение и измените его на "Больше или равно". Измените константу на 20.

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

Ответ 2

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

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

Держите прокрутку:)

Ответ 3

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

Если что-то неясно, не стесняйтесь оставлять комментарий.

import UIKit

class TutorialView: UIView {

    lazy var sv: UIScrollView = {
        let object = UIScrollView()

        object.backgroundColor = UIColor.whiteColor()
        object.translatesAutoresizingMaskIntoConstraints = false
        return object
    }()

    lazy var tutorialPageOne: UIView = {
        let object = UIView(frame: UIScreen.mainScreen().bounds)
        object.translatesAutoresizingMaskIntoConstraints = false
        object.backgroundColor = UIColor.cyanColor()

        return object
    }()

    lazy var tutorialPageTwo: UIView = {
        let object = UIView(frame: UIScreen.mainScreen().bounds)
        object.translatesAutoresizingMaskIntoConstraints = false
        object.backgroundColor = UIColor.lightGrayColor()

        return object
    }()

    lazy var tutorialPageThree: UIView = {
        let object = UIView(frame: UIScreen.mainScreen().bounds)
        object.translatesAutoresizingMaskIntoConstraints = false
        object.backgroundColor = UIColor.redColor()

        return object
    }()

    override init(frame: CGRect) {
        super.init(frame: frame)

        self.addSubview(self.sv)
        self.sv.addSubview(self.tutorialPageOne)
        self.sv.addSubview(self.tutorialPageTwo)
        self.sv.addSubview(self.tutorialPageThree)
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    override func layoutSubviews() {
        super.layoutSubviews()

        let vc = nextResponder() as? UIViewController
        let mainSreenWidth = UIScreen.mainScreen().bounds.size.width
        let mainScreenHeight = UIScreen.mainScreen().bounds.size.height

        NSLayoutConstraint.activateConstraints([
            self.sv.topAnchor.constraintEqualToAnchor(vc?.topLayoutGuide.bottomAnchor),
            self.sv.leadingAnchor.constraintEqualToAnchor(self.leadingAnchor),
            self.sv.bottomAnchor.constraintEqualToAnchor(vc?.bottomLayoutGuide.topAnchor),
            self.sv.trailingAnchor.constraintEqualToAnchor(self.trailingAnchor)
        ])

        NSLayoutConstraint.activateConstraints([
            self.tutorialPageOne.widthAnchor.constraintEqualToConstant(mainSreenWidth),
            self.tutorialPageOne.heightAnchor.constraintEqualToConstant(mainScreenHeight),
            self.tutorialPageOne.topAnchor.constraintEqualToAnchor(self.sv.topAnchor),
            self.tutorialPageOne.leadingAnchor.constraintEqualToAnchor(self.sv.leadingAnchor),
            self.tutorialPageOne.bottomAnchor.constraintEqualToAnchor(self.sv.bottomAnchor)
        ])


        NSLayoutConstraint.activateConstraints([
            self.tutorialPageTwo.widthAnchor.constraintEqualToConstant(mainSreenWidth),
            self.tutorialPageTwo.heightAnchor.constraintEqualToConstant(mainScreenHeight),
            self.tutorialPageTwo.topAnchor.constraintEqualToAnchor(self.sv.topAnchor),
            self.tutorialPageTwo.leadingAnchor.constraintEqualToAnchor(self.tutorialPageOne.trailingAnchor),
            self.tutorialPageTwo.bottomAnchor.constraintEqualToAnchor(self.sv.bottomAnchor)
        ])

        NSLayoutConstraint.activateConstraints([
            self.tutorialPageThree.widthAnchor.constraintEqualToConstant(mainSreenWidth),
            self.tutorialPageThree.heightAnchor.constraintEqualToConstant(mainScreenHeight),
            self.tutorialPageThree.topAnchor.constraintEqualToAnchor(self.sv.topAnchor),
            self.tutorialPageThree.leadingAnchor.constraintEqualToAnchor(self.tutorialPageTwo.trailingAnchor),
            self.tutorialPageThree.bottomAnchor.constraintEqualToAnchor(self.sv.bottomAnchor),
            self.tutorialPageThree.trailingAnchor.constraintEqualToAnchor(self.sv.trailingAnchor)
        ])

    }
}

Ответ 4

Тем, кто ищет пример UIScrollView и AutoLayout. Я использую SnapKit, он работает для Xcode 9, Swift 3

    let scrollView = UIScrollView()
    view.addSubview(scrollView)
    scrollView.snp.makeConstraints { (make) in
        make.edges.equalTo(view).inset(UIEdgeInsetsMake(0, 0, 0, 0))
        make.top.left.right.equalTo(view)
    }

    let view1 = UIView()
    view1.backgroundColor = UIColor.red
    scrollView.addSubview(view1)
    view1.snp.makeConstraints { (make) in
        make.top.equalTo(scrollView.snp.top).offset(0)
        make.left.equalTo(scrollView.snp.left).offset(0)
        make.width.equalTo(scrollView.snp.width)
        make.height.equalTo(300)
    }

    let view2 = UIView()
    view2.backgroundColor = UIColor.blue
    scrollView.addSubview(view2)
    view2.snp.makeConstraints { (make) in
        make.top.equalTo(view1.snp.bottom)
        make.left.equalTo(scrollView)
        make.width.equalTo(scrollView)
        make.height.equalTo(300)
    }

    let view3 = UIView()
    view3.backgroundColor = UIColor.green
    scrollView.addSubview(view3)
    view3.snp.makeConstraints { (make) in
        make.top.equalTo(view2.snp.bottom)
        make.left.equalTo(scrollView)
        make.width.equalTo(scrollView)
        make.height.equalTo(100)
        make.bottom.equalTo(scrollView.snp.bottom).offset(-20)
    }

Ответ 5

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

Ограничения для подзонов в представлении прокрутки должны приводить к заполнению размера, который затем интерпретируется как размер содержимого прокрутки. (Это не следует путать с методом intrinsicContentSize, используемым для автоматической компоновки.) Чтобы размер кадра представлений прокрутки с помощью Auto Layout, ограничения должны быть либо явными относительно ширины и высоты прокрутки, либо края прокрутки должны быть привязан к представлениям вне своего поддерева.

См. также Technote. Apple написала об этой проблеме: https://developer.apple.com/library/ios/technotes/tn2154/_index.html

Ответ 6

Лучший способ узнать, как создать пользовательский интерфейс внутри scrollView без кода:

  • Добавьте свой scrollView в uiviewcontroller с соответствующими ограничениями между ним и его родительским представлением.
  • Добавить "вид скобки" в прокрутку.
  • "Просмотр скобок" должен быть скрыт, так как он не отличается от вашего окончательного интерфейса.
  • Сделать левое, верхнее, правое, заключено между "скобкой" и UIScrollView. Сделайте ограничение по высоте. (Ограничение по высоте может быть любым числом). Сделайте выравнивание центра x с ограничениями UIScrollView.

  • Добавьте свой конечный пользовательский интерфейс под "графическим представлением".

  • Добавьте верхнее ограничение между первым окончательным представлением пользовательского интерфейса и "представлением скобок".
  • Соедините все ваши окончательные представления пользовательского интерфейса вместе с ограничениями сверху или снизу.
  • Добавьте правильные ограничения конечного интерфейса.
  • Добавьте нижние ограничения между последним окончательным представлением пользовательского интерфейса и видом прокрутки. (Этот параметр constraint.constant важен, поскольку он отличается от вашего конечного интерфейса).

Вот пример github project.

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

Ответ 7

В соответствии с @m1234, однако вам нужно освободить равную высоту, иначе прокрутка не будет работать - мой метод будет таким:

  • Добавить представление прокрутки в виде подматрицы основного вида.

  • Выберите "Просмотр прокрутки" и снимите флажок "Ограничение на поля" и нажмите "Верх", "Влево", "Вправо", "Вниз", "Ограничения"

  • Добавьте UIView в качестве подзаголовка вида прокрутки. Назовите это представление "Просмотр содержимого"

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

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

  • Добавьте все элементы, которые вам нужны в представлении содержимого. Свяжите верхние, левые, правые и высотные ограничения с добавленными элементами.

  • В самом низу в элементе содержимого в представлении содержимого указывается нижнее ограничение. Выберите это ограничение и измените его на "Больше или равно". Измените константу на 20.