轉(zhuǎn)載地址:https://blog.csdn.net/gang544043963/article/details/52440621
用到自動約束吠架,就離不開一下四個方法:
@interface UIView (UIConstraintBasedLayoutCoreMethods)
- (void)updateConstraintsIfNeeded NS_AVAILABLE_IOS(6_0); // Updates the constraints from the bottom up for the view hierarchy rooted at the receiver. UIWindow's implementation creates a layout engine if necessary first.
- (void)updateConstraints NS_AVAILABLE_IOS(6_0); // Override this to adjust your special constraints during a constraints update pass
- (BOOL)needsUpdateConstraints NS_AVAILABLE_IOS(6_0);
- (void)setNeedsUpdateConstraints NS_AVAILABLE_IOS(6_0);
@end
而這四個方法衣式,對于它們的具體的用途和調(diào)用時機(jī)理解,很長一段時間我是迷迷糊糊的夫否。經(jīng)過一番研究,現(xiàn)在就試著把它解釋清楚7岣琛6杳薄!
- (void)updateConstraintsIfNeeded
官網(wǎng)文檔的解釋:
Updates the constraints for the receiving view and its subviews.
Whenever a new layout pass is triggered for a view, the system invokes this method to ensure that any constraints for the view and its subviews are updated with information from the current view hierarchy and its constraints. This method is called automatically by the system, but may be invoked manually if you need to examine the most up to date constraints.
Subclasses should not override this method.
更新視圖和它的子視圖的約束召噩。
每當(dāng)一個新的布局母赵,通過觸發(fā)一個視圖,系統(tǒng)調(diào)用此方法以確保視圖和其子視圖的任何約束與當(dāng)前視圖層次結(jié)構(gòu)和約束信息更新具滴。這種方法被系統(tǒng)自動調(diào)用凹嘲,但如果需要檢查最新的約束條件,可以手動調(diào)用這個方法构韵。
子類不應(yīng)重寫此方法周蹭。
注解:立即出發(fā)約束更新。 ?????
- (void)updateConstraints
官網(wǎng)文檔的解釋:
Updates constraints for the view.
Custom views that set up constraints themselves should do so by overriding this method. When your custom view notes that a change has been made to the view that invalidates one of its constraints, it should immediately remove that constraint, and then call setNeedsUpdateConstraints to note that constraints need to be updated. Before layout is performed, your implementation of updateConstraints will be invoked, allowing you to verify that all necessary constraints for your content are in place at a time when your custom view’s properties are not changing.
You must not invalidate any constraints as part of your constraint update phase. You also must not invoke a layout or drawing phase as part of constraint updating.
Important:Important
Call [super updateConstraints] as the final step in your implementation.
更新視圖的約束疲恢。
自定義視圖應(yīng)該通過重寫此方法來設(shè)置自己的約束凶朗。當(dāng)你的自定義視圖有某個約束發(fā)生了變化或失效了,應(yīng)該立即刪除這個約束显拳,然后調(diào)用setNeedsUpdateConstraints標(biāo)記約束需要更新棚愤。系統(tǒng)在進(jìn)行布局layout之前,會調(diào)用updateConstraints杂数,讓你確認(rèn)(設(shè)置)在視圖的屬性不變時的必要約束宛畦。在更新約束階段你不應(yīng)該使任何一個約束失效,而且不能讓layerout和drawing作為更新約束的一部分揍移。
重要提示:要在實現(xiàn)的最后調(diào)用[super updateConstraints]次和。
注解:自定義view應(yīng)該重寫此方法在其中建立constraints.
- (BOOL)needsUpdateConstraints
這個很簡單,返回是否需要更新約束羊精。constraint-based layout system使用此返回值去決定是否需要調(diào)用updateConstraints作為正常布局過程的一部分斯够。
- (void)setNeedsUpdateConstraints
官方文檔解釋:
Controls whether the view’s constraints need updating.
When a property of your custom view changes in a way that would impact constraints, you can call this method to indicate that the constraints need to be updated at some point in the future. The system will then call updateConstraints as part of its normal layout pass. Updating constraints all at once just before they are needed ensures that you don’t needlessly recalculate constraints when multiple changes are made to your view in between layout passes.
控制視圖的約束是否需要更新。
當(dāng)你的自定義視圖的屬性改變切影響到約束喧锦,你可以調(diào)用這個方法來標(biāo)記未來的某一點上需要更新的約束读规。然后系統(tǒng)將調(diào)用updateconstraints。
注解:這個方法和updateConstraintsIfNeeded關(guān)系有點曖昧燃少,updateConstraintsIfNeeded是立即更新束亏,二這個方法是標(biāo)記需要更新,然后系統(tǒng)決定更新時機(jī)阵具。
這里再補(bǔ)充一下Auto layout知識
Auto layout在view顯示之前碍遍,還有兩個步驟:updating constraints 和laying out views定铜。每一個步驟都依賴于上一個。display依賴layout怕敬,而layout依賴updating constraints揣炕。 updating constraints->layout->display
第一步:updating constraints愁拭,被稱為測量階段扎唾,其從下向上(from subview to super view),為下一步layout準(zhǔn)備信息倦春∫牛可以通過調(diào)用方法setNeedUpdateConstraints去觸發(fā)此步混聊。constraints的改變也會自動的觸發(fā)此步恨樟。但是粤咪,當(dāng)你自定義view的時候叹放,如果一些改變可能會影響到布局的時候斋日,通常需要自己去通知Auto layout牲览,updateConstraintsIfNeeded。
自定義view的話恶守,通车谙祝可以重寫updateConstraints方法,在其中可以添加view需要的局部的contraints熬的。
第二步:layout痊硕,其從上向下(from super view to subview),此步主要應(yīng)用上一步的信息去設(shè)置view的center和bounds押框〔沓瘢可以通過調(diào)用setNeedsLayout去觸發(fā)此步驟,此方法不會立即應(yīng)用layout橡伞。如果想要系統(tǒng)立即的更新layout盒揉,可以調(diào)用layoutIfNeeded。另外兑徘,自定義view可以重寫方法layoutSubViews來在layout的工程中得到更多的定制化效果刚盈。
第三步:display,此步時把view渲染到屏幕上挂脑,它與你是否使用Auto layout無關(guān)藕漱,其操作是從上向下(from super view to subview),通過調(diào)用setNeedsDisplay觸發(fā)崭闲,
因為每一步都依賴前一步肋联,因此一個display可能會觸發(fā)layout,當(dāng)有任何layout沒有被處理的時候刁俭,同理橄仍,layout可能會觸發(fā)updating constraints,當(dāng)constraint system更新改變的時候。
需要注意的是侮繁,這三步不是單向的虑粥,constraint-based layout是一個迭代的過程,layout過程中宪哩,可能去改變constraints娩贷,有一次觸發(fā)updating constraints,進(jìn)行一輪layout過程斋射。
注意:如果你每一次調(diào)用自定義layoutSubviews都會導(dǎo)致另一個布局傳遞育勺,那么你將會陷入一個無限循環(huán)中。