概覽
UIStackView 為單行或者單列提供自動布局、自動伸縮特性,UIScorllview 提供的特性則contentSize 大于frame.size時可以滑動的特性,理論上將二者的特性結(jié)合起來就能實現(xiàn)線性文檔流布局,布局從上之下進(jìn)行排列。
使用場景
對于一些樣式非常復(fù)雜的列表,需要為每一種樣式單獨定義一個cell類,每個cell的功能各自不同,如果使用 UITableView 和 UICollectionView來實現(xiàn),那么就會在代理方法里面寫好多判斷邏輯(想想你的 UITableView 代理方法是不是寫了 if、else if、switch),有時候一個
- tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath方法里面右上百行代碼,甚至更多。這時候使用線性文檔流布局是最好不過的選擇,將不同樣式的組件各自進(jìn)行封裝,各自處理各自的事件, 然后將組件實例通過 UIStactView 的 addArrangedSubview 添加到布局流中去,UIStactView 會根據(jù)添加順序依次進(jìn)行布局。表視圖的高度是一個動態(tài)性的高度,像有一些場景中文本需要展開和收起功能,使用列表視圖實現(xiàn)是比較復(fù)雜的,而使用 UIStackView 實現(xiàn)就簡單很多了,組件內(nèi)部只需要管理內(nèi)部的約束關(guān)系,UIStackView 自動實現(xiàn)伸縮。
有限集列表,對于無限集列表還是推薦使用 UITableView 或者 UICollectionView, 原因不用多說(UICollectionView 和 UITableView 提供 cell 的復(fù)用機(jī)制,在性能方面更優(yōu))
舉幾個例子:



以上三個頁面全部使用UIStackView 作為容器搭建完成
首先看一下 UIStackView 實現(xiàn)線性布局結(jié)構(gòu)圖

具體步驟
創(chuàng)建相關(guān)視圖
override func viewDidLoad() {
super.viewDidLoad()
let scrollView = UIScrollView()
scrollView.backgroundColor = UIColor.red
let stackView = UIStackView()
stackView.axis = .vertical // 縱向布局
stackView.distribution = .equalSpacing // 每個item之間間距相同
stackView.spacing = 20 // 相鄰item之間間距
stackView.alignment = .center // 居中對齊,不對item進(jìn)行橫向拉伸
view.addSubview(scrollView)
scrollView.addSubview(stackView)
for i in 0..<10 {
let itemView = UIButton()// 為了演示效果這里采用 uibutton,點擊消失對 UIStackView 布局的影響
itemView.setTitle("View\(i)", for: .normal)
itemView.addTarget(self, action: #selector(handle), for: .touchUpInside)
itemView.backgroundColor = .green
stackView.addArrangedSubview(itemView)
}
}
@objc func handle(btn:UIButton) {
UIView.animate(withDuration: 0.25) {
btn.isHidden = true
}
}
UIScorllview 約束設(shè)置
scrollView.snp.makeConstraints { (make) in
make.edges.equalTo(self.view)
}
UIStackView 約束設(shè)置,關(guān)鍵步驟,設(shè)置 stackView 定寬或者像下面這樣,依賴于 scrollView 的父視圖寬度,高度依賴棧內(nèi)子視圖將其撐開,并撐開 scrollView 的 contentSize
stackView.snp.makeConstraints { (make) in
make.left.right.equalTo(self.view)
make.top.bottom.equalTo(scrollView)
}
UIStackView 棧內(nèi)子視圖約束設(shè)置
itemView.snp.makeConstraints { (make) in
make.height.equalTo(200)
make.width.equalTo(self.view.frame.width - 40)
}
預(yù)覽效果

總結(jié)
UIStackView 是 蘋果官方在iOS 9.0 推出的非常先進(jìn)的容器視圖,結(jié)合自動布局能夠快速的幫助開發(fā)者完成各種布局效果。我在開發(fā)《海馬體照相館》app 的過程中大量的使用了 UIStackView,有時間的話分享一篇 UIStackView 的其他方面的應(yīng)用。