Auto Layout的生命周期
Auto Layout 不只有布局算法 Cassowary老玛,還包含了布局在運行時的生命周期等一整套布局引擎系統(tǒng)淤年,用來統(tǒng)一管理布局創(chuàng)建钧敞、更新和銷毀。這套系統(tǒng)叫做Layout Engine
Auto Layout布局流程
關(guān)于Auto Layout的布局流程互亮,Apple給出圖示如上:即Layout Cycle是一個在App運行循環(huán)RunLoop下循環(huán)執(zhí)行的一個過程犁享。
App啟動后開啟RunLoop,循環(huán)檢測圖層樹中是否存在約束變化豹休;
當(dāng)發(fā)生Constrints Change(直接or間接設(shè)置炊昆、更新、移除約束),RunLoop檢測到約束變化威根;
RunLoop發(fā)現(xiàn)約束變化后凤巨,就會進入Deferred Layout階段,視圖的位置洛搀、尺寸值會在這個過程計算敢茁,設(shè)置到對應(yīng)視圖上,并繪制出來留美;
執(zhí)行完一輪布局彰檬,RunLoop會繼續(xù)檢查視圖樹的約束更新情況,當(dāng)再次發(fā)現(xiàn)約束更新谎砾,則執(zhí)行新一輪布局……
Constraints Change (約束變化)
Constraints Change過程包括兩個步驟:約束更新逢倍;Layout Engine重新計算布局,獲取到布局后調(diào)用superview.setNeedLayout()
,然后進入Deferred Layout Pass景图。
Deferred Layout Pass (延遲布局)
Deferred Layout Pass 分為兩步:
- 更新約束:從下往上(子視圖到父視圖)较雕,依次遍歷視圖層級,調(diào)用View的
updateConstraints
方法(或ViewController的updateViewConstraints
方法)來更新約束(你可以在此覆蓋本方法來設(shè)置自定義約束挚币,且在此設(shè)置時亮蒋,執(zhí)行效率最高。記得最后調(diào)用父類實現(xiàn))妆毕。 - 給視圖及子視圖重新設(shè)定位置(給view的frame賦值):從上到下依次調(diào)用View的layoutSubViews方法(或ViewController的viewLayoutSubViews方法)慎玖,從Layout Engine中取出預(yù)算好的frame進行賦值(你可以覆蓋此方法實現(xiàn)自定義布局,不過此刻不是穩(wěn)態(tài)设塔,需要在適合時候調(diào)用父類實現(xiàn))凄吏。
延遲布局的觸發(fā)條件
setNeedsUpdateConstraints
下一次loop執(zhí)行updateConstraints
updateConstraintsIfNeeded
立即執(zhí)行updateConstraints
setNeedsLayout
下一次loop執(zhí)行l(wèi)ayoutSubViews
layoutIfNeeded
立即執(zhí)行l(wèi)ayoutSubViews
setNeedDisplay
下一次loop執(zhí)行draw
view的改變會調(diào)用哪些方法
- 改變
frame.origin
不會掉用layoutSubviews
- 改變
frame.size
會使superVIew
的layoutSubviews
調(diào)用 - 改變
bounds.origin
和bounds.size
都會調(diào)用superView
和自己view
的layoutSubviews
方法
參考鏈接:https://github.com/ming1016/study/wiki/深入剖析Auto-Layout,分析iOS各版本新增特性