我正在编写一个以编程方式初始化的自定义视图。我覆盖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 文章 http://www.objc.io/issue-3/advanced-auto-layout-toolbox.html,这是预期的,因为框架直到layoutSubviews
叫做。它还提到
要强制系统立即更新视图树的布局,您可以调用layoutIfNeeded
/layoutSubtreeIfNeeded
(分别在 iOS 和 OS X 上)。如果您的后续步骤依赖于最新的视图框架,这会很有帮助。
但是,当我添加
[self setNeedsLayout];
[self layoutIfNeeded];
就在设置之前self.bottomSpacingConstraint
in updateConstraints
,我仍然得到一个CGRectZero
回到框架。根据 objc.io 文章(以及这个所以答案 https://stackoverflow.com/a/20846449/751268),这些方法应该触发布局并更新框架。
有人可以阐明如何使这一切发挥作用吗?我对解决方案以及导致调用哪些与布局相关的方法的原因感兴趣(例如,似乎更改现有约束的常量layoutSubviews
causes setNeedsUpdateConstraints
被调用,然后触发updateConstraints
并导致约束被添加多次)。
我很确定你不能或不应该打电话layoutIfNeeded
from updateConstraints
。更新约束是在布局周期的早期部分,所以我认为它不会产生您想要的效果。
在您的情况下,解决方案是检查constant
layoutSubviews 中依赖于框架的约束的属性,如果需要更新,请在那里更新或调用setNeedsUpdateConstraints
(小心引起循环)。
你说过更新约束会触发另一个调用updateConstraints
- 这是真的,我认为你滥用了updateConstraints
- 那是为了updating基于视图内容更改的约束。仅当这些约束尚不存在时,您才应添加它们。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)