現在iOS頁面布局用的最多的就是frame和Autolayout,實際上Autolayout的約束最終都是由系統轉換成frame來進行布局的。而當Autolayout與frame設置上產生沖突時,則會以Autolayout的設置為準。
跟布局相關的方法
- (void)setNeedsLayout;
- (void)layoutIfNeeded;
- (void)layoutSubviews;
setNeedsLayout方法標記當前view是需要重新布局的,在下一次runloop中,進行重新布局。如果想在當前的runloop中立刻更新布局,則通過調用layoutIfNeeded方法可以實現,此時系統會調用layoutSubviews,在layoutSubviews方法中,可以自己定義新的view或者改變子view的布局。
Autolayout相關的方法
//view的方法
- (void)updateConstraintsIfNeeded;
//重寫view中的方法
- (void)updateConstraints
- (BOOL)needsUpdateConstraints
- (void)setNeedsUpdateConstraints
//重寫viewController中的方法
- (void)updateViewConstraints
setNeedsUpdateConstraints只是標記當前view的約束需要在下一次runloop中更新,updateConstraintsIfNeeded如果過滿足更新條件會立刻調用updateConstraints來更新約束,updateConstraints是子view需要重寫的方法,來更新View的約束,最后需要調用[super updateConstraints],否則會崩。而updateViewConstraints是定義在viewController中的,方便去更新viewController對應view的約束。
具體可以通過調用view的setNeedsUpdateConstraints來最終調用到viewController的updateViewConstraints方法來,如果沒有這個方法,那么每次都要定義一個子view去重寫updateConstraints方法會比較繁瑣。updateConstraints和updateViewConstrains方法可以把約束的代碼和和業務邏輯分開,另外性能也更好。
為什么會有setxxxxx和xxxifNeeded方法
setxxxxx方法可能是為了性能,沒有在代碼更新布局或者約束之后立刻執行,而是在下一次runloop中執行。
xxxxIfNeeded方法則是為了在必要的時候,立刻更新約束或者布局,舉個例子,有些時候同時使用動畫和autolayout。