滚动视图在实际开发中用到的地方有很多, 可以使用代码创建, 或者是使用 nib 加载, 这里就分别来看上述两种创建方式下, 如何结合自动布局来设置滚动视图内容.
在开发实践中, 个人比较推崇使用 Xib 来实现场景的整体框架, 而使用代码来实现视图中的细部内容, 以提高开发效率.
下面来看看在使用自动布局的情况下, 如何通过 xib 以及代码创建滚动视图(UIScrollView)及其内容.
滚动视图: Xib + AutoLayout
- 拖入一个滚动视图, 如下所示, 并将其约束到父视图的四边:
(这里使用的 StoryBoard, 故需要约束到最底层 View 的四边上, 如果使用 Xib, 可以直接在底层放滚动视图)

- 在滚动视图上拖入一个
UIView, 它将作为滚动视图的contentView:
contentView 的约束设置有:
-
四周约束到滚动视图上
-
高度等于滚动视图高度, 优先级设置为低(重要)
-
宽度等于滚动视图宽度

经过上述两个步骤, 滚动视图的 contentSize 就已经可以根据内容计算了.
剩下就是利用自动布局往 contentView 中添加子视图, 需要注意在滚动方向上的最后一个子视图需要将其滚动方向上的边约束到内容视图上, 如下所示:

运行后效果如下所示:

滚动视图: 代码 + AutoLayout
代码实现的套路基本上和 Xib 实现一致, 下面分步骤讲解:
- 新建视图控制器, 设置两个属性分别持有滚动视图和滚动视图的内容视图:
import UIKit class ScrollE2ViewController: UIViewController { private var _scrollView: UIScrollView! private var _contentView: UIView! // ... }
- 设置滚动视图:
private func setupScrollView() { _scrollView = UIScrollView() view.addSubview(_scrollView) _scrollView.snp.makeConstraints { $0.edges.equalToSuperview() } }
- 设置内容视图:
private func setupContentView() { _contentView = UIView() _scrollView.addSubview(_contentView) _contentView.snp.makeConstraints { $0.edges.equalToSuperview() $0.width.equalToSuperview() $0.height.equalToSuperview().priority(250) } }
- 布局内容视图内部的子视图:
private func setupContentSubViews() { let v1 = UIView() v1.backgroundColor = .red _contentView.addSubview(v1) v1.snp.makeConstraints { $0.top.leading.trailing.equalToSuperview() $0.height.equalTo(400) } let v2 = UIView() v2.backgroundColor = .blue _contentView.addSubview(v2) v2.snp.makeConstraints { // 最下面的这个视图底部需要约束到内容视图底部, 即下面的 .bottom 表达的约束 $0.leading.trailing.bottom.equalToSuperview() $0.top.equalTo(v1.snp.bottom).offset(20) $0.height.equalTo(400) } }
实现效果如下所示:
