2017-02-20 67 views
0

,當我寫這樣的代碼行之有效添加子視圖那麼,是否可以在layoutSubviews使用自動佈局

@interface SubView() 
@property(nonatomic,strong) UIButton* btn; 
@end 

@implementation SubView 


- (void)layoutSubviews 
{ 
    [super layoutSubviews]; 
    [self.btn removeFromSuperview]; 
    self.btn = [UIButton buttonWithType:UIButtonTypeCustom]; 
    self.btn.backgroundColor = [UIColor greenColor]; 
    [self.btn setTitle:@"btn" forState:UIControlStateNormal]; 
    self.btn.translatesAutoresizingMaskIntoConstraints = NO; 
    [self addSubview:self.btn]; 

    NSLayoutConstraint* centerXConstraint = [self.btn.centerXAnchor constraintEqualToAnchor:self.centerXAnchor]; 
    NSLayoutConstraint* centerYConstraint = [self.btn.centerYAnchor constraintEqualToAnchor:self.centerYAnchor]; 
    [self addConstraint:centerXConstraint]; 
    [self addConstraint:centerYConstraint]; 
} 
@end 

但在我看來,當使用自動佈局,系統將分兩步1個更新做佈局經過2佈局傳遞,而layoutSubviews在步驟2中(佈局傳遞)

所以如果我們在layoutSubviews添加子視圖,它看起來像它會改變看法的制約,所以我們需要做的更新通和佈局通再次,所以它會產生一個無限循環..

但事實上,這段代碼運行良好,所以我錯在哪裏?

+1

添加'subView'不會改變視圖的約束,因此'layoutSubviews'不會被調用。然而'layoutSubviews'不是添加子視圖的好地方,最好是在初始化程序中完成。 –

+0

你的意思是上面的centerXConstraint不是視圖的約束,而是子視圖的約束?所以視圖的layoutSubviews可以排列右邊 – ximmyxiao

+0

是的,它只是將按鈕對齊到視圖的centerX,這不會影響視圖本身的位置/大小。當視圖的框架發生變化時,或者如果您執行'setNeedsLayout'或'layoutIfNeeded'手動觸發佈局,則會調用'layouSubiviews'。 –

回答

2

請注意,layoutSubviews將被多次調用。它每次刪除按鈕並重新添加它有什麼意義?

另外,layoutSubviews是自動佈局系統服從約束的地方。那麼在layoutSubviews中設置按鈕的約束有什麼意義?

即使它似乎正在工作,你在做什麼都沒有任何意義在layoutSubviews。一次完成這項任務並在其他地方完成。

+0

謝謝@matt,我在updateConstraints中看到過一些代碼(比如我上面發佈的),所以在updateConstraints中添加/刪除子視圖也是一個不好的習慣? – ximmyxiao

+0

@ximmyxiao是的。在其他地方做,如viewDidLoad。 – Shebuka

+0

@Shebuka如果它是在一個自定義的uiview中,它看起來像初始化方法將是做這種事情的唯一好地方? – ximmyxiao

相關問題