Swift:我无法使自动布局限制适用于我的UIScrollView

时间:2017-06-08 10:03:45

标签: ios swift uiscrollview autolayout

我尝试制作一个简单的布局,当视图太多而无法放在屏幕上时,该布局应垂直滚动。

所以这就是我到目前为止:

我创建了一个scrollview和一个像

这样的容器视图
let mainScrollView: UIScrollView = {

    let scrollView = UIScrollView()

    scrollView.isUserInteractionEnabled = true
    scrollView.translatesAutoresizingMaskIntoConstraints = false

    return scrollView
}()

let containerView: UIView = {

    let view = UIView()

    view.backgroundColor = .lightGray
    view.translatesAutoresizingMaskIntoConstraints = false

    return view
}()

然后我将scrollview添加到主视图,将容器视图添加到scrollview,并将几个标签添加到容器视图

view.addSubview(mainScrollView)
mainScrollView.addSubview(containerView)

containerView.addSubview(firstLabel)
containerView.addSubview(secondLabel)

我将scrollview固定到主视图,将容器视图固定到scrollview。之后我开始在容器视图中添加标签,如下所示

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

containerView.topAnchor.constraint(equalTo: mainScrollView.layoutMarginsGuide.topAnchor).isActive = true
containerView.bottomAnchor.constraint(equalTo: mainScrollView.layoutMarginsGuide.bottomAnchor).isActive = true
containerView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
containerView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true

firstLabel.centerXAnchor.constraint(equalTo: containerView.centerXAnchor).isActive = true
firstLabel.topAnchor.constraint(equalTo: containerView.topAnchor, constant: 30).isActive = true
firstLabel.widthAnchor.constraint(equalToConstant: 50).isActive = true
firstLabel.heightAnchor.constraint(equalToConstant: 20).isActive = true

secondLabel.centerXAnchor.constraint(equalTo: containerView.centerXAnchor).isActive = true
secondLabel.topAnchor.constraint(equalTo: firstLabel.bottomAnchor, constant: 750).isActive = true
secondLabel.widthAnchor.constraint(equalToConstant: 50).isActive = true
secondLabel.heightAnchor.constraint(equalToConstant: 20).isActive = true

问题是由于某种原因,滚动视图无法计算它的高度而且它不会垂直滚动。第二个标签仍然是隐形的,因为它太低了#34;低的#34;在屏幕上。

我尝试将容器视图的底部约束设置到第二个标签的底部,但我没有说实话。

我错过了什么?如何设置约束以使滚动视图滚动自动布局(不设置容器视图的特定高度)?

2 个答案:

答案 0 :(得分:3)

Scrollview向两个方向滚动。因此,添加到其中的任何视图都需要一些额外的约束才能让Scrollview计算其内容大小。

您已将容器视图固定为滚动视图。如果您正在查看垂直滚动视图(如表视图),则还需要将滚动的宽度设置为容器视图,以便它可以计算宽度。

接下来是高度,它会根据容器视图中添加的UI元素自动计算。确保所有标签都具有前导,尾随容器和彼此之间的垂直间距以及容器视图的顶部。这将使滚动视图知道所需的高度。

    self.scrollView.translatesAutoresizingMaskIntoConstraints = false
    self.contentView.translatesAutoresizingMaskIntoConstraints = false
    self.label1.translatesAutoresizingMaskIntoConstraints = false
    self.label2.translatesAutoresizingMaskIntoConstraints = false
    self.label3.translatesAutoresizingMaskIntoConstraints = false

    self.contentView.addSubview(self.label1)
    self.contentView.addSubview(self.label2)
    self.contentView.addSubview(self.label3)

    self.scrollView.addSubview(self.contentView)
    self.view.addSubview(self.scrollView)

    NSLayoutConstraint.activate([
        self.scrollView.topAnchor.constraint(equalTo: self.view.topAnchor),
        self.scrollView.trailingAnchor.constraint(equalTo: self.view.trailingAnchor),
        self.scrollView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor),
        self.scrollView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor)
    ])

    NSLayoutConstraint.activate([
        self.contentView.topAnchor.constraint(equalTo: self.scrollView.topAnchor),
        self.contentView.trailingAnchor.constraint(equalTo: self.scrollView.trailingAnchor),
        self.contentView.bottomAnchor.constraint(equalTo: self.scrollView.bottomAnchor),
        self.contentView.leadingAnchor.constraint(equalTo: self.scrollView.leadingAnchor),
        self.contentView.widthAnchor.constraint(equalTo: self.scrollView.widthAnchor)
    ])

    NSLayoutConstraint.activate([
        self.label1.leadingAnchor.constraint(equalTo: self.contentView.leadingAnchor),
        self.label2.leadingAnchor.constraint(equalTo: self.contentView.leadingAnchor),
        self.label3.leadingAnchor.constraint(equalTo: self.contentView.leadingAnchor),
        self.label1.trailingAnchor.constraint(equalTo: self.contentView.trailingAnchor),
        self.label2.trailingAnchor.constraint(equalTo: self.contentView.trailingAnchor),
        self.label3.trailingAnchor.constraint(equalTo: self.contentView.trailingAnchor)
    ])

    NSLayoutConstraint.activate([
        self.label1.topAnchor.constraint(equalTo: self.contentView.topAnchor),
        self.label2.topAnchor.constraint(equalTo: self.label1.bottomAnchor),
        self.label3.topAnchor.constraint(equalTo: self.label2.bottomAnchor),
        self.label3.bottomAnchor.constraint(equalTo: self.contentView.bottomAnchor)
    ])

运行时,它也不会抱怨任何约束问题。水平滚动也可以这样做。

enter image description here

答案 1 :(得分:1)

非常感谢@ GoodSp33d,你指出了我正确的方向。

我按照你的说法添加了宽度约束:

containerView.widthAnchor.constraint(equalTo: mainScrollView.widthAnchor).isActive = true

关键是要更新底部约束:

containerView.bottomAnchor.constraint(equalTo: secondLabel.bottomAnchor).isActive = true

以下是完整的工作代码:

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

containerView.topAnchor.constraint(equalTo: mainScrollView.topAnchor).isActive = true
containerView.trailingAnchor.constraint(equalTo: mainScrollView.trailingAnchor).isActive = true
containerView.bottomAnchor.constraint(equalTo: mainScrollView.bottomAnchor).isActive = true
containerView.leadingAnchor.constraint(equalTo: mainScrollView.leadingAnchor).isActive = true
containerView.widthAnchor.constraint(equalTo: mainScrollView.widthAnchor).isActive = true

firstLabel.centerXAnchor.constraint(equalTo: containerView.centerXAnchor).isActive = true
firstLabel.topAnchor.constraint(equalTo: containerView.topAnchor, constant: 30).isActive = true
firstLabel.widthAnchor.constraint(equalToConstant: 50).isActive = true
firstLabel.heightAnchor.constraint(equalToConstant: 20).isActive = true

secondLabel.centerXAnchor.constraint(equalTo: containerView.centerXAnchor).isActive = true
secondLabel.topAnchor.constraint(equalTo: firstLabel.bottomAnchor, constant: 550).isActive = true
secondLabel.widthAnchor.constraint(equalToConstant: 50).isActive = true
secondLabel.heightAnchor.constraint(equalToConstant: 20).isActive = true

containerView.bottomAnchor.constraint(equalTo: secondLabel.bottomAnchor).isActive = true

感谢您的帮助。