UIView中與AutoLayout相關的幾個方法對比

根本停不下來發表於2018-04-24

UIView中有幾個關於layout的方法,長的很相似。根據官方文件和網上大部分的說法都難以理解它們有什麼實用性,因為都沒有給出可以參考的程式碼。下面是我自己目前簡單的理解,以後有新的發現了會再新增進去。

-(void)updateConstraints

用於自定義view的時候重寫該方法,向其中新增約束。

-(void)setNeedsUpdateConstraints

官方:Controls whether the view’s constraints need updating. 不清楚這句話有什麼實用性。
我的發現:呼叫該方法,會呼叫updateConstraints
     在一個UIViewController中執行[self.view setNeedsUpdateContraints]會呼叫UIViewController中的- (void)updateViewConstraints,在UIViewController中約束的更新寫在updateViewConstraints裡面,在UIViewController中想要更新約束的話可以使用[self.view setNeedsUpdateContraints]

示例:
1.在alloc init該view的時候,系統會先呼叫一次updateConstraints,佈置好約束。
2.點選_button後觸發didTapButton:方法,self.buttonSize發生改變。呼叫setNeedsUpdateConstraints後系統自動呼叫updateConstraints,更新約束。
3.最後的layoutIfNeed程式碼是為了新增動畫效果。

- (void)updateConstraints {
    [_button updateConstraints:^(MASConstraintMaker *make) {
        make.center.equalTo(self);
        make.width.equalTo(@(self.buttonSize.width));
        make.height.equalTo(@(self.buttonSize.height));
        make.width.lessThanOrEqualTo(self);
        make.height.lessThanOrEqualTo(self);
     }];
    //according to apple super should be called at end of method
    [super updateConstraints];
}

- (void)didTapButton:(UIButton *)button {
    self.buttonSize = CGSizeMake(self.buttonSize.width * 1.3, self.buttonSize.height * 1.3);
    
    [self setNeedsUpdateConstraints];
    
    //新增動畫效果
    [UIView animateWithDuration:0.4 animations:^{
        [self layoutIfNeeded];
    }];
}
複製程式碼

-(void)updateConstraintsIfNeeded

官方的說法是:Updates the constraints for the receiving view and its subviews.
應該是說呼叫該方法會更新view的約束。但是,如果我用程式碼改變了view的約束,它會是自動的就變了,不需要呼叫updateConstraintsIfNeeded;我在呼叫updateConstraintsIfNeeded的時候也沒有發現它會呼叫updateConstraints
所以,暫時沒有發現updateConstraintsIfNeeded有什麼用。


更新

在網上看見了別人回答問題:UIView中layoutIfNeeded的用法? 的答案:

這個方法和另一個方法配對的,setNeedLayout和layoutIfNeed,還有一個關聯的方法是layoutSubviews,在我們沒有任何干預的情況下,一個view的fram或bounds發生變化時,系統會設定一個flag給這個view,當下一個渲染時機到來時系統會重新按新的佈局來渲染檢視。setNeedLayout就是我們主動為這個檢視設定一個flag,告訴系統這個檢視再下一個時機到來時要重新渲染,而layoutIfNeed則是告訴系統,如果設定了flag那麼不用等待時機到來了,直接渲染吧。而layoutSubviews這個方法是系統呼叫的,我們不需要主動呼叫,我們只需要呼叫layoutIfNeed就可以了,讓系統判斷是否在當前時機下立即渲染。

相關文章