iOS開發-setNeedsLayout, layoutIfNeeded 和 layoutSubviews 方法的理解

更新佈局總會重新觸發layoutSubviews方法。

1.layoutSubviews

繼承於UIView的子類重寫,進行佈局更新,刷新視圖。
如果某個視圖自身的bounds或者子視圖的bounds發生改變,那麼這個方法會在當前runloop結束的時候被調用。
爲什麼不是立即調用呢?因爲渲染畢竟比較消耗性能,特別是視圖層級複雜的時候。這種機制下任何UI控件佈局上的變動不會立即生效,而是每次間隔一個週期,所有UI控件在佈局上的變動統一生效並且在視圖上更新。

runloop的observer回調=>
CoreAnimation渲染引擎一次事務的提交=>
CoreAnimation遞歸查詢圖層是否有佈局上的更新=>
CALayer layoutSublayers=>
UIView layoutSubviews 

可以看到UIView其實就是相當於CALayer的代理。

2.setNeedsLayout

標記爲需要重新佈局,異步調用layoutIfNeeded刷新佈局,不立即刷新,在下一輪runloop結束前刷新,對於這一輪runloop之內的所有佈局和UI上的更新只會刷新一次,layoutSubviews一定會被調用。

3.layoutIfNeeded

如果有需要刷新的標記,立即調用layoutSubviews進行佈局(如果沒有標記,不會調用layoutSubviews)。

4.在當前runloop中立即刷新

layoutIfNeeded不一定會調用layoutSubviews方法。
setNeedsLayout一定會調用layoutSubviews方法(有延遲,在下一輪runloop結束前)。
如果想在當前runloop中立即刷新,調用順序應該是

[self setNeedsLayout];
[self layoutIfNeeded];

反之可能會出現佈局錯誤的問題。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章