Не удается добавить подпредставление в scrollView - PullRequest
0 голосов
/ 21 февраля 2020

Я так растерялся. Я не могу заставить какие-либо подпредставления появляться в scrollView

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

Что я делаю неправильно ??

import UIKit

class MainViewController: UIViewController {

    var scrollView: UIScrollView {
        let scrollView = UIScrollView(frame: CGRect(x: 0.0, y: 0.0, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height))
        scrollView.isPagingEnabled = true
        scrollView.backgroundColor = .orange
        scrollView.contentSize = CGSize(width: UIScreen.main.bounds.width * 3.0, height:  UIScreen.main.bounds.height)
        return scrollView
    }

    var leftViewController: UIViewController {
        let vC = UIViewController()
        vC.view.backgroundColor = .purple
        return vC
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        view.addSubview(scrollView)
        leftViewController.view.frame = .init(x: 0, y: 0, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height)
        addChild(leftViewController)
        scrollView.addSubview(leftViewController.view)
        leftViewController.didMove(toParent: self)
    }
}

может достичь того, что мне нравится, с помощью автоматического макета, хотя жесткая ширина кодирования все же высока .

class MainViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        view.addSubview(scrollView)
        scrollView.addSubview(scrollViewContainer)
        scrollViewContainer.addArrangedSubview(redView)
        scrollViewContainer.addArrangedSubview(blueView)
        scrollViewContainer.addArrangedSubview(greenView)

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

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

    let scrollView: UIScrollView = {
        let scrollView = UIScrollView()
        scrollView.isPagingEnabled = true
        scrollView.translatesAutoresizingMaskIntoConstraints = false
        return scrollView
    }()

    let scrollViewContainer: UIStackView = {
        let view = UIStackView()
        view.axis = .horizontal
        view.translatesAutoresizingMaskIntoConstraints = false
        return view
    }()

    let redView: UIView = {
        let view = UIView()
        view.widthAnchor.constraint(equalToConstant: UIScreen.main.bounds.width).isActive = true
        view.heightAnchor.constraint(equalToConstant: UIScreen.main.bounds.height).isActive = true
        view.backgroundColor = .red
        return view
    }()

    let blueView: UIView = {
        let view = UIView()
        view.widthAnchor.constraint(equalToConstant: UIScreen.main.bounds.width).isActive = true
        view.heightAnchor.constraint(equalToConstant: UIScreen.main.bounds.height).isActive = true
        view.backgroundColor = .blue
        return view
    }()

    let greenView: UIView = {
        let view = UIView()
        view.widthAnchor.constraint(equalToConstant: UIScreen.main.bounds.width).isActive = true
        view.heightAnchor.constraint(equalToConstant: UIScreen.main.bounds.height).isActive = true
        view.backgroundColor = .green
        return view
    }()
}

1 Ответ

1 голос
/ 21 февраля 2020

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

var scrollView: UIScrollView = {
    let scrollView = UIScrollView(frame: CGRect(x: 0.0, y: 0.0, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height))
    scrollView.isPagingEnabled = true
    scrollView.backgroundColor = .orange
    scrollView.contentSize = CGSize(width: UIScreen.main.bounds.width * 3.0, height:  UIScreen.main.bounds.height)
    return scrollView
}()

var leftViewController: UIViewController = {
    let vC = UIViewController()
    vC.view.backgroundColor = .purple
    return vC
}()

Обратите внимание на = и добавление () в конце, чтобы указать, что они инициализируются с замыканиями.

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


В своем пересмотренном вопросе вы поделились кодом, используя ограничения. Если вы используете ограничения, убедитесь, что вы установили translatesAutoresizingMaskIntoConstraints на false для всех соответствующих представлений. В противном случае он автоматически преобразует маску автоматического изменения размера представления в ограничения, которые будут конфликтовать с новыми ограничениями, которые вы добавляете вручную.

И вам также следует избегать constraint(equalToConstant:), используя constraint(equalTo:), ссылаясь на основной посмотреть, где это возможно. Например:

class ViewController: UIViewController {
    let scrollView: UIScrollView = {
        let view = UIScrollView()
        view.translatesAutoresizingMaskIntoConstraints = false
        view.isPagingEnabled = true
        return view
    }()

    let redView: UIView = {
        let view = UIView()
        view.translatesAutoresizingMaskIntoConstraints = false
        view.backgroundColor = .red
        return view
    }()

    let greenView: UIView = {
        let view = UIView()
        view.translatesAutoresizingMaskIntoConstraints = false
        view.backgroundColor = .green
        return view
    }()

    override func viewDidLoad() {
        super.viewDidLoad()

        view.addSubview(scrollView)
        scrollView.addSubview(redView)
        scrollView.addSubview(greenView)

        NSLayoutConstraint.activate([
            // set the scroll view to be the size of the main view

            scrollView.topAnchor.constraint(equalTo: view.topAnchor),
            scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
            scrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
            scrollView.trailingAnchor.constraint(equalTo: view.trailingAnchor),

            // set the subviews to be the size of the main view, too

            redView.widthAnchor.constraint(equalTo: view.widthAnchor),
            redView.heightAnchor.constraint(equalTo: view.heightAnchor),

            greenView.widthAnchor.constraint(equalTo: view.widthAnchor),
            greenView.heightAnchor.constraint(equalTo: view.heightAnchor),

            // now dictate where these subviews are in the scroll view vertically ...

            redView.topAnchor.constraint(equalTo: scrollView.topAnchor),
            greenView.topAnchor.constraint(equalTo: scrollView.topAnchor),

            redView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor),
            greenView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor),

            // ... and horizontally

            redView.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor),
            greenView.leadingAnchor.constraint(equalTo: redView.trailingAnchor),
            greenView.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor)
        ])
    }
}

Честно говоря, поскольку вы говорите о полноэкранных дочерних контроллерах, я бы полностью отбросил этот код и просто использовал UIPageViewController (что не только выводит нас из бизнес по определению размеров представлений верхнего уровня контроллера дочерних представлений, но также позволяет нам более эффективно создавать «своевременные» контроллеры дочерних представлений).

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...