故事從一年前提及,當時因爲接到一個新項目開發任務開發以前想了想之前項目UI
佈局方式大多數都是frame
計算有的也用到masonry
。
frame
你們都知道適配各類屏幕很是繁瑣各類座標size
計算代碼很冗餘後期難以維護。
masonry
開源給iOS開發者帶來福音簡化了AutoLayout
使用方式,可是我以爲masonry
還不足夠快捷方便(有的api不知道什麼意思學習成本比較高),尤爲是動態佈局masonry
更新約束至關不方便,後來就決定本身開發AutoLayout
庫也就是今天WHC_AutoLayoutKit。javascript
在閱讀以前能夠先看看例子項目:github.com/netyouli/WH… java
UITableViewCell
高度模塊帶緩存高度WHC_StackView
模塊(目的替代系統UIStackView
)view.whc_Left(10) //view與父視圖左邊距10
.whc_Right(10) //view與父視圖右邊距10
.whc_Height(40) //view自身高度40
.whc_Top(64) //view與父視圖頂邊距64複製代碼
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return UITableViewCell.whc_CellHeightForIndexPath(indexPath, tableView: tableView)
}複製代碼
什麼叫隱式更新,顧名思義就是在你添加同類型約束(可能會產生衝突約束)會自動刪除前面添加可能產生衝突的約束(更新約束)看下面例子:git
override func viewDidLoad() {
super.viewDidLoad()
let view = UIView()
self.view.addSubview(view)
view.whc_Left(10) //view與父視圖左邊距10
.whc_Right(10) //view與父視圖右邊距10
.whc_HeightAuto() //view高度自動
.whc_Top(64) //view與父視圖頂邊距64
}複製代碼
有時候程序執行的過程當中根據需求須要動態調整UI佈局假如點擊按鈕上面view高度調整固定64代碼以下:github
// 單獨更新height約束
private func clickButton(sender: UIButton) {
view.whc_Height(64) // 只須要執行這一行代碼便可更新view高度爲64
}複製代碼
上面這個代碼執行作了什麼事情呢?
他會檢查view
高度方向是否有同類型可能衝突約束若是檢查到那麼會刪除上面添加的HeightAuto
約束而後添加新Height
固定約束64。
默認狀況固定高度約束優先級比自動高度約束高因此即便不刪除上面HeightAuto
也不要緊,可是有時候會由於約束衝突程序崩潰。再好比點擊按鈕以下修改:swift
// 單獨更新top約束
private func clickButton(sender: UIButton) {
view.whc_Top(10, toView: otherView) //viwe 頂部間隙到otherView底部爲10
}複製代碼
一樣上面的代碼執行以前會檢查y方向是否有同類型約束(可能衝突的約束),顯然view.whc_Top(10)
和view.whc_Top(10, toView: otherView)
確定是衝突的,因此在執行上面代碼WHC_AutoLayout會先刪除view
的whc_Top(10)
約束而後再添加whc_Top(10, toView: otherView)
約束。
上面解釋就是隱式更新約束技術而不須要像masonry從新重寫view全部約束那麼麻煩。api
override func viewDidLoad() {
super.viewDidLoad()
let view = UIView()
self.view.addSubview(view)
let label = UILabel()
self.view.addSubview(label)
label.text = "xxxxxxxxxxxxxxxxxxxxx"
label.whc_Left(10) //label左到view左邊距10
.whc_Right(10) //label右到view右邊距10
.whc_Top(10) //label頂到view頂邊距10
.whc_HeightAuto() //label高度自動
.whc_Bottom(10, keepHeightConstraint: true) //label底到view底邊距10,而且保留label高度
view.whc_Left(10) //view與父視圖左邊距10
.whc_Right(10) //view與父視圖右邊距10
.whc_Top(64) //view與父視圖頂邊距64
.whc_HeightAuto() //view高度自動
}複製代碼
效果以下:
緩存
view
高度須要自動根據
label
高度自動調整,而
label
高度自己是自動的若是不添加
label
與
view
的底邊距
whc_Bottom
關係約束
view
沒法根據
label
高度變化而變化。
那可能又有人疑問?
whc_Bottom(10, keepHeightConstraint: true)
裏的
keepHeightConstraint
是什麼意思?前面介紹了
WHC_AutoLayout是隱式更新約束技術然而很顯然
label
上
whc_HeightAuto
通常狀況和
whc_Bottom
是同類型約束(衝突約束)因此這兩個通常狀況只能存在一個約束,可是iOS有一種特殊狀況須要
Height
約束和
Bottom
約束同時存在那就是在
view
自動高度的時候(
bottom
爲了撐開父視圖由於父視圖是自動高度因此須要一個自動高度參照約束)或者
view
底邊距對齊(不採用
top
對齊)的時候如:
label.whc_Left(10) //label左到view左邊距10
.whc_Right(10) //label右到view右邊距10
.whc_HeightAuto() //label高度自動
.whc_Bottom(10, keepHeightConstraint: true) //label底部間隙和父視圖底部10複製代碼
上面label
就是一種從下往上佈局。iview
從上面的例子與介紹能夠咱們能夠對WHC_AutoLayout得出以下結論:ide
keep
的約束API時候無論後面添加多少約束永遠只會存在4個view
須要高度或者寬度自動適應時候其view
上最後一個控件須要用到5個約束(這個時候須要用到帶keep
的API,一樣從下或者從右開始佈局有時候也須要)WHC_StackView
後面會有專門的文章詳細介紹1.x方向同類型約束(不會對寬度產生影響):Left
,Leading
,Trailing
,CenterX
(包含ToView
...)
注意WHC_AutoLayout對Leading
和Trailing
特殊處理理論上他們是能夠成對使用的爲了統一性把他們歸爲同類約束Leading
左對齊Trailing
又對齊
2.y方向同類型約束(不會對寬度產生影響):Top
,BaseLineSpace
,CenterY
(包含ToView
...)
3.寬度方向同類型約束(對寬度產生影響):Width
,Right
(包含ToView
,自動寬度...)
4.高度方向同類型約束(對高度產生影響):Height
,Bottom
(包含ToView
,自動高度...)佈局
WHC_AutoLayout開源地址:github.com/netyouli/WH…
本人其餘優秀開源項目:github.com/netyouli/
謝謝你的耐心閱讀