水平滚动视图滚动但仅部分滚动并弹回原始位置

Horizontal scroll view scrolls but only partially and bounces back to original position

我有一个水平滚动视图,内容如下:

当我 运行 它会部分水平滚动 - 我可以滚动直到看到大约一半的红色视图,然后它会反弹回来。 我怎样才能得到它,让它可以一直滚动,所以所有的红色视图都是可见的,然后停留在那里?

我在视图控制器中有这个,但是有没有都没有关系。

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    print("Content view bounds: \(contentView.bounds)")
    scrollView.layoutIfNeeded()
    scrollView.contentSize = contentView.bounds.size
}

在情节提要的屏幕截图中,红色视图没有后缘约束,但是如果我在红色视图和内容视图之间添加一个,那么当我在设备上 运行 时,它会停止滚动并且看起来像这样:

我通过添加以下内容让它工作:

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    scrollView.contentSize = CGSize(width: 750,height: 812)
}

但是为什么上面的可以,下面的不行呢?

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    print("Content view bounds: \(contentView.bounds)")
    scrollView.layoutIfNeeded()
    scrollView.contentSize = contentView.bounds.size
}

在运行时 contentView.bounds 是 (0.0, 0.0, 750.0, 812.0)

开始时您不需要明确设置 .contentSize -- 您可以让 auto-layout 为您处理所有事情。

首先,删除您的 Content View.width = width 约束:

让那个约束告诉 auto-layout 让你的 contentView 只和 滚动视图一样宽,所以你不会得到任何水平滚动。通过显式设置 .contentSize,您可以进行一些滚动,但是您发现它并没有给您想要的东西。

删除该约束后,从 Red View 添加一个 20 磅的尾部约束到内容视图的尾部边缘:

现在,你有一个完整的水平约束链...

- Blue View.leading = leading + 20
- Blue View Width
- Red View.leading = Blue View.trailing + 40
- Red View Width
- trailing = Red View.trailing + 20

这满足 auto-layout 并正确定义 Content View 的宽度...并且由于 Content View 被限制为滚动视图的前导和尾随,因此您可以获得正确的水平滚动。

无需任何代码。