iOS version: 12.2
字数:900+
阅读时长:10 min
复制代码
在平常开发中,使人看了就想素质三连的代码,莫过于手动计算各类数字的代码。以下图,看了真的是头皮发麻。bash
下面,咱们举一个实际的例子来一步一步的实现:使用 AutoLayout 自动计算 ScrollView 的 contentSize 。ide
优先级要低
(这一步很重要,千万不要写错)首先,给使用的 scrollView 添加完整的约束:ui
// 1. 设置 scrollView 的约束
view.addSubview(scrollView)
scrollView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
scrollView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
scrollView.leftAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leftAnchor),
scrollView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor),
scrollView.rightAnchor.constraint(equalTo: view.safeAreaLayoutGuide.rightAnchor)
])
复制代码
设置完 scrollView,接下来设置 contentView 的约束:spa
// 2. 设置 contentView
let contentView = UIView(frame: .zero)
scrollView.addSubview(contentView)
contentView.translatesAutoresizingMaskIntoConstraints = false
let contentViewHeightAnchor = contentView.heightAnchor.constraint(equalTo: view.safeAreaLayoutGuide.heightAnchor)
// 2.1 高度和 scrollView 的父视图相等,且`优先级要低`
contentViewHeightAnchor.priority = UILayoutPriority(rawValue: 1)
NSLayoutConstraint.activate([
contentView.topAnchor.constraint(equalTo: scrollView.topAnchor),
contentView.leftAnchor.constraint(equalTo: scrollView.leftAnchor),
contentView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor),
contentView.rightAnchor.constraint(equalTo: scrollView.rightAnchor),
contentView.widthAnchor.constraint(equalTo: view.widthAnchor),
contentViewHeightAnchor
])
复制代码
设置完 scrollView 和 contentView 的约束,只需设置内部子控件的约束,剩下的工做就能够交给 AutoLayout 去作了。code
// 3.添加子控件,设置内部约束
titleLabel.text = "titleLabel"
contentView.addSubview(titleLabel)
titleLabel.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
titleLabel.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 10),
titleLabel.leftAnchor.constraint(equalTo: contentView.leftAnchor, constant: 10),
titleLabel.rightAnchor.constraint(equalTo: contentView.rightAnchor, constant: -10)
])
contentLabel.text = "将此处替换为你本身的字符串(超过一屏),便可看见滑动效果。"
contentLabel.numberOfLines = 0
contentView.addSubview(contentLabel)
contentLabel.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
contentLabel.topAnchor.constraint(equalTo: titleLabel.bottomAnchor, constant: 10),
contentLabel.leftAnchor.constraint(equalTo: titleLabel.leftAnchor),
contentLabel.rightAnchor.constraint(equalTo: titleLabel.rightAnchor)
])
bottomLabel.text = "bottomLabel"
contentView.addSubview(bottomLabel)
bottomLabel.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
bottomLabel.topAnchor.constraint(equalTo: contentLabel.bottomAnchor, constant: 10),
bottomLabel.leftAnchor.constraint(equalTo: titleLabel.leftAnchor),
bottomLabel.rightAnchor.constraint(equalTo: titleLabel.rightAnchor),
bottomLabel.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -10)
])
复制代码
到这里,咱们就大功告成了。妈妈不再用担忧我手动计算数字了😏 (成功保住了本身的头发)。cdn
class TestViewController: UIViewController {
let scrollView = UIScrollView(frame: .zero)
let titleLabel = UILabel(frame: .zero)
let contentLabel = UILabel(frame: .zero)
let bottomLabel = UILabel(frame: .zero)
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = UIColor.white
setupSubviews()
}
}
extension TestViewController {
func setupSubviews() {
// 1. 设置 scrollView 的约束
view.addSubview(scrollView)
scrollView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
scrollView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
scrollView.leftAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leftAnchor),
scrollView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor),
scrollView.rightAnchor.constraint(equalTo: view.safeAreaLayoutGuide.rightAnchor)
])
// 2. 设置 contentView
let contentView = UIView(frame: .zero)
scrollView.addSubview(contentView)
contentView.translatesAutoresizingMaskIntoConstraints = false
let contentViewHeightAnchor = contentView.heightAnchor.constraint(equalTo: view.safeAreaLayoutGuide.heightAnchor)
// 2.1 高度和 scrollView 的父视图相等,且`优先级要低`
contentViewHeightAnchor.priority = UILayoutPriority(rawValue: 1)
NSLayoutConstraint.activate([
contentView.topAnchor.constraint(equalTo: scrollView.topAnchor),
contentView.leftAnchor.constraint(equalTo: scrollView.leftAnchor),
contentView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor),
contentView.rightAnchor.constraint(equalTo: scrollView.rightAnchor),
contentView.widthAnchor.constraint(equalTo: view.widthAnchor),
contentViewHeightAnchor
])
// 3.添加子控件,设置内部约束
titleLabel.text = "titleLabel"
contentView.addSubview(titleLabel)
titleLabel.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
titleLabel.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 10),
titleLabel.leftAnchor.constraint(equalTo: contentView.leftAnchor, constant: 10),
titleLabel.rightAnchor.constraint(equalTo: contentView.rightAnchor, constant: -10)
])
contentLabel.text = "将此处替换为你本身的字符串(超过一屏),便可看见滑动效果"
contentLabel.numberOfLines = 0
contentView.addSubview(contentLabel)
contentLabel.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
contentLabel.topAnchor.constraint(equalTo: titleLabel.bottomAnchor, constant: 10),
contentLabel.leftAnchor.constraint(equalTo: titleLabel.leftAnchor),
contentLabel.rightAnchor.constraint(equalTo: titleLabel.rightAnchor)
])
bottomLabel.text = "bottomLabel"
contentView.addSubview(bottomLabel)
bottomLabel.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
bottomLabel.topAnchor.constraint(equalTo: contentLabel.bottomAnchor, constant: 10),
bottomLabel.leftAnchor.constraint(equalTo: titleLabel.leftAnchor),
bottomLabel.rightAnchor.constraint(equalTo: titleLabel.rightAnchor),
bottomLabel.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -10)
])
}
}
复制代码
效果图:blog