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