滚动视图内的内容视图-为什么?

时间:2019-04-16 12:04:21

标签: ios xcode

我看到几乎每个人都在情节提要中的 scroll view 中使用虚拟视图。 滚动视图本身不是视图吗?

此官方Apple docs link中指出:

  

对于大多数常见的布局任务,如果您使用虚拟视图或布局组来包含滚动视图的内容,则逻辑变得容易得多。

我确实尝试直接使用滚动视图而不是使用内容视图(虚拟视图)作为中介,但发现自己处于便秘状态,但我没有知道为什么。

这是我的问题:

  1. 为什么直接使用滚动视图会变得困难,怎么变得困难?
  2. 什么是?如何使用布局组作为替代?
  3. 如何在没有中间虚拟视图的情况下直接使用滚动视图

2 个答案:

答案 0 :(得分:1)

查看是否在滚动视图中使用内容视图,在使用自动布局的情况下,无需以编程方式计算和设置滚动视图的内容大小,因为UI元素将自动布局约束设置为内容视图,并且内容视图将更改根据用户界面元素内容的大小。滚动视图具有两种不同的功能,一种是其框架,另一种是其内容大小。因此,如果不使用内容视图层,则必须根据UI元素内容手动设置滚动视图的内容大小。请检查:https://medium.com/@pradeep_chauhan/how-to-configure-a-uiscrollview-with-auto-layout-in-interface-builder-218dcb4022d7

答案 1 :(得分:1)

通常,元素是动态添加的。许多人发现将它们添加到“内容视图”比将它们直接添加到滚动视图更容易。

我个人认为直接方法更容易。

没有虚拟/内容视图,您只需将元素限制为滚动视图本身,而不是内容视图。

这里有两个例子。 ContentScrollViewControllerDirectScrollViewController。如您所见,它们几乎是相同的。这实际上是一个优先选择的问题……您 start 使用的任何一种方法可能都是您喜欢的方法。注意:出于演示的目的,我经常给元素提供完全不同的背景颜色,以使其易于查看布局框架。

内容查看方法:

class ContentScrollViewController: UIViewController {

    let topLabel: UILabel = {
        let v = UILabel()
        v.translatesAutoresizingMaskIntoConstraints = false
        v.backgroundColor = .green
        v.text = "Top Label"
        return v
    }()

    let bottomLabel: UILabel = {
        let v = UILabel()
        v.translatesAutoresizingMaskIntoConstraints = false
        v.backgroundColor = .green
        v.text = "Top Label"
        return v
    }()

    let contentView: UIView = {
        let v = UIView()
        v.translatesAutoresizingMaskIntoConstraints = false
        v.backgroundColor = .orange
        return v
    }()

    let scrollView: UIScrollView = {
        let v = UIScrollView()
        v.translatesAutoresizingMaskIntoConstraints = false
        v.backgroundColor = .red
        return v
    }()

    override func viewDidLoad() {
        super.viewDidLoad()

        view.addSubview(scrollView)
        scrollView.addSubview(contentView)
        contentView.addSubview(topLabel)
        contentView.addSubview(bottomLabel)

        NSLayoutConstraint.activate([

            // constrain scrollView to all 4 sides with 20-pts padding
            scrollView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 20.0),
            scrollView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: -20.0),
            scrollView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor, constant: 20.0),
            scrollView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor, constant: -20.0),

            // constrain contentView to all 4 sides of scrollView with 8-pts padding
            contentView.topAnchor.constraint(equalTo: scrollView.topAnchor, constant: 8.0),
            contentView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor, constant: -8.0),
            contentView.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor, constant: 8.0),
            contentView.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor, constant: -8.0),

            // constrain topLabel 0-pts to top and leading of contentView
            topLabel.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 0.0),
            topLabel.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 0.0),

            // constrain bottomLabel's top 800-pts from bottom of topLabel
            bottomLabel.topAnchor.constraint(equalTo: topLabel.bottomAnchor, constant: 800.0),

            // constrain bottomLabel's leading 600-pts from trailing of topLabel
            bottomLabel.leadingAnchor.constraint(equalTo: topLabel.trailingAnchor, constant: 600.0),

            // constrain bottomLabel 0-pts to bottom and trailing of contentView
            bottomLabel.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: 0.0),
            bottomLabel.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: 0.0),

            ])

    }

}

直接方法:

class DirectScrollViewController: UIViewController {

    let topLabel: UILabel = {
        let v = UILabel()
        v.translatesAutoresizingMaskIntoConstraints = false
        v.backgroundColor = .green
        v.text = "Top Label"
        return v
    }()

    let bottomLabel: UILabel = {
        let v = UILabel()
        v.translatesAutoresizingMaskIntoConstraints = false
        v.backgroundColor = .green
        v.text = "Top Label"
        return v
    }()

    let scrollView: UIScrollView = {
        let v = UIScrollView()
        v.translatesAutoresizingMaskIntoConstraints = false
        v.backgroundColor = .red
        return v
    }()

    override func viewDidLoad() {
        super.viewDidLoad()

        view.addSubview(scrollView)
        scrollView.addSubview(topLabel)
        scrollView.addSubview(bottomLabel)

        NSLayoutConstraint.activate([

            // constrain scrollView to all 4 sides with 20-pts padding
            scrollView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 20.0),
            scrollView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: -20.0),
            scrollView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor, constant: 20.0),
            scrollView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor, constant: -20.0),

            // constrain topLabel 8-pts to top and leading of scrollView
            topLabel.topAnchor.constraint(equalTo: scrollView.topAnchor, constant: 8.0),
            topLabel.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor, constant: 8.0),

            // constrain bottomLabel's top 800-pts from bottom of topLabel
            bottomLabel.topAnchor.constraint(equalTo: topLabel.bottomAnchor, constant: 800.0),

            // constrain bottomLabel's leading 600-pts from trailing of topLabel
            bottomLabel.leadingAnchor.constraint(equalTo: topLabel.trailingAnchor, constant: 600.0),

            // constrain bottomLabel 8-pts to bottom and trailing of scrollView
            bottomLabel.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor, constant: -8.0),
            bottomLabel.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor, constant: -8.0),

            ])

    }

}