用到自動約束底挫,就離不開一下四個方法:
@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
而這四個方法,對于它們的具體的用途和調用時機理解脸侥,很長一段時間我是迷迷糊糊的建邓。經(jīng)過一番研究,現(xiàn)在就試著把它解釋清楚U稣怼9俦摺沸手!
- (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.
更新視圖和它的子視圖的約束。
每當一個新的布局注簿,通過觸發(fā)一個視圖罐氨,系統(tǒng)調用此方法以確保視圖和其子視圖的任何約束與當前視圖層次結構和約束信息更新。這種方法被系統(tǒ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.
更新視圖的約束。
自定義視圖應該通過重寫此方法來設置自己的約束恩袱。當你的自定義視圖有某個約束發(fā)生了變化或失效了泣棋,應該立即刪除這個約束,然后調用setNeedsUpdateConstraints標記約束需要更新畔塔。系統(tǒng)在進行布局layout之前潭辈,會調用updateConstraints,讓你確認(設置)在視圖的屬性不變時的必要約束澈吨。在更新約束階段你不應該使任何一個約束失效把敢,而且不能讓layerout和drawing作為更新約束的一部分。
重要提示:要在實現(xiàn)的最后調用[super updateConstraints]谅辣。
注解:自定義view應該重寫此方法在其中建立constraints.
- (BOOL)needsUpdateConstraints
這個很簡單修赞,返回是否需要更新約束。constraint-based layout system使用此返回值去決定是否需要調用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.
控制視圖的約束是否需要更新柏副。
當你的自定義視圖的屬性改變切影響到約束,你可以調用這個方法來標記未來的某一點上需要更新的約束蚣录。然后系統(tǒng)將調用updateconstraints割择。
注解:這個方法和updateConstraintsIfNeeded關系有點曖昧,updateConstraintsIfNeeded是立即更新,二這個方法是標記需要更新,然后系統(tǒng)決定更新時機座韵。
這里再補充一下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準備信息译荞。可以通過調用方法setNeedUpdateConstraints去觸發(fā)此步休弃。constraints的改變也會自動的觸發(fā)此步吞歼。但是,當你自定義view的時候塔猾,如果一些改變可能會影響到布局的時候篙骡,通常需要自己去通知Auto layout,updateConstraintsIfNeeded丈甸。
自定義view的話糯俗,通常可以重寫updateConstraints方法睦擂,在其中可以添加view需要的局部的contraints得湘。
第二步:layout,其從上向下(from super view to subview)顿仇,此步主要應用上一步的信息去設置view的center和bounds淘正。可以通過調用setNeedsLayout去觸發(fā)此步驟臼闻,此方法不會立即應用layout鸿吆。如果想要系統(tǒng)立即的更新layout,可以調用layoutIfNeeded述呐。另外伞剑,自定義view可以重寫方法layoutSubViews來在layout的工程中得到更多的定制化效果。
第三步:display市埋,此步時把view渲染到屏幕上黎泣,它與你是否使用Auto layout無關,其操作是從上向下(from super view to subview)缤谎,通過調用setNeedsDisplay觸發(fā)抒倚,
因為每一步都依賴前一步,因此一個display可能會觸發(fā)layout坷澡,當有任何layout沒有被處理的時候托呕,同理项郊,layout可能會觸發(fā)updating constraints斟赚,當constraint system更新改變的時候拗军。
需要注意的是蓄喇,這三步不是單向的交掏,constraint-based layout是一個迭代的過程盅弛,layout過程中,可能去改變constraints罐柳,有一次觸發(fā)updating constraints张吉,進行一輪layout過程催植。
注意:如果你每一次調用自定義layoutSubviews都會導致另一個布局傳遞创南,那么你將會陷入一個無限循環(huán)中。
出處 https://blog.csdn.net/gang544043963/article/details/52440621