我正在編寫一個以編程方式初始化的自定義視圖。我重寫updateConstraints
以添加此視圖所需的所有約束。 :在約束依賴於框架的自定義視圖中使用自動佈局
- (void)updateConstraints {
[self.superview addConstraint:[NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self.superview attribute:NSLayoutAttributeCenterX multiplier:1 constant:0]];
[self.superview addConstraint:[NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.superview attribute:NSLayoutAttributeTop multiplier:1 constant:0]];
[self.superview addConstraint:[NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.superview attribute:NSLayoutAttributeBottom multiplier:1 constant:0]];
// some more constraints, you get the point
self.bottomSpacingConstraint = [NSLayoutConstraint constraintWithItem:self.imageView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeBottom multiplier:1 constant:-(0.2 * CGRectGetHeight(self.bounds))];
[self addConstraint:self.bottomSpacingConstraint];
[super updateConstraints];
}
的問題是,self.bounds
返回CGRectZero
相當。我做了我的研究,根據這objc.io article,這是預期的,因爲框架不會被設置,直到調用layoutSubviews
。它還提到
要強制系統立即更新視圖樹的佈局,可以(分別在iOS和OS X)調用
layoutIfNeeded
/layoutSubtreeIfNeeded
。如果您的後續步驟依賴於視圖的幀更新,這可能會有所幫助。
然而,當我就在updateConstraints
設置self.bottomSpacingConstraint
前加
[self setNeedsLayout];
[self layoutIfNeeded];
,我仍然獲得了CGRectZero
回來的框架。根據objc.io文章(和這SO answer),這些方法應該觸發佈局和更新框架。
任何人都可以點亮如何使這一切工作?我感興趣的解決方案,以及是什麼原因導致其佈局相關的方法被稱爲解釋(例如,看來,改變現有的約束在layoutSubviews
原因setNeedsUpdateConstraints
不斷被調用,然後觸發updateConstraints
並導致限制要多次添加)。
這是蘋果公司說,大約'updateConstraints':*實現此方法,如果您需要,以創建子視圖之間的自定義約束,*現在,它並沒有明確地說,他們應建立在** **'updateConstraints ',但這就是它所暗示的,我相信。如果不是,我會在哪裏創建這些約束條件? –
我不是說不要在那裏創建它們。我只是說只有在它們不存在時才創建它們,因爲可以多次調用該方法。 – jrturton
不夠公平,但我不想濫用'updateConstraints'。如果該方法是不是真的,我要創建的約束,那麼我完全好創建別的地方。我只是不知道什麼會是一個更好的地方。如果'updateConstraints' * *是正確的地方,我將包裝在檢查其不存在的if語句創建,第一。 –