首發於公衆號前端
在 iOS 中官方支持的佈局方式是 AutoLayout,是一種基於控件之間相互約束關係的自動佈局工具。程序員
官方的 AutoLayout 雖然用起來簡單,可是有兩個很是不方便的地方:swift
第1個問題可使用第三方庫來解決,好比 SnapKit(swift)、Masonry(oc)。 性能問題則無解,對於混合佈局的 Cell 若是所有使用自動佈局就會看到很明顯的滑動卡頓。app
對於複雜 Cell 佈局,程序員們爲了追求極致的幀率,通常都採用手寫佈局,幀率是上去了而維護的成本也最高。ide
爲了兼顧易用性和高效率,Facebook 開發並開源了本身的佈局庫:Yoga。工具
Yoga 是 FlexBox 的子集,並無所有實現 FlexBox,可是對於大部分應用場景已經足夠了。佈局
接觸過前端開發的朋友對 FlexBox 佈局必定不陌生,CSS 寫 flex 佈局真的太方便了。性能
FlexBox 是不一樣於 AutoLayout 的佈局方式,FlexBox 是自約束,每一個控件的位置都是相對於自身所在的 Box 相對佈局,這就不存在 AutoLayout 基於控件間約束的耦合。flex
Yoga 是基於手動佈局的方式,這樣效率就很高,並且性能損耗很小,並且使用很簡單,用過 Masonry 的同窗能夠很快上手。spa
使用方法:
override init(frame: CGRect) {
super.init(frame: frame)
contentView.configureLayout { (layout) in
layout.isEnabled = true
}
override func layoutSubviews() {
super.layoutSubviews()
yoga.applyLayout(preservingOrigin: true)
}
複製代碼
layout.isEnabled = true 開啓 yoga 佈局, 在 layoutSubviews 中使用 applyLayout 自動調整佈局。
這和手動佈局的流程是同樣的,能夠看出來 yoga 本質上也是手動佈局,只是不再用手算座標了。
yoga 同時也有很好的易用性,好比要實現一個簡單的九宮格,只須要簡單的設置一下佈局參數。
override init(frame: CGRect) {
super.init(frame: frame)
configureLayout { (layout) in
layout.isEnabled = true
}
contentView = UIView(frame: bounds)
addSubview(contentView)
contentView.configureLayout { (layout) in
layout.isEnabled = true
layout.flexDirection = .row
layout.flexWrap = .wrap
layout.flexGrow = 1
}
for _ in 0...8 {
let imageView = UIImageView(frame: .zero)
imageView.backgroundColor = .orange
contentView.addSubview(imageView)
imageView.configureLayout { (layout) in
layout.isEnabled = true
layout.width = 86
layout.height = 86
layout.marginTop = 10
layout.marginLeft = 10
}
}
}
override func layoutSubviews() {
super.layoutSubviews()
yoga.applyLayout(preservingOrigin: true)
}
複製代碼
核心參數是 layout.flexWrap = .wrap ,讓視圖佈局自動換行,再計算好間距和寬高,這樣就實現了九宮格的排列效果。
運行的效果: