[英]Using auto-layout in a custom view where constraints rely on frame
我正在编写一个以编程方式初始化的自定义视图。 我重写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文章 ,这是预期的,因为在调用layoutSubviews
之前框架不会被设置。 它也提到了
要强制系统立即更新视图树的布局,可以调用
layoutIfNeeded
/layoutSubtreeIfNeeded
(分别在iOS和OS X上)。 如果您的后续步骤依赖于视图框架是最新的,这可能会有所帮助。
但是,当我添加
[self setNeedsLayout];
[self layoutIfNeeded];
在updateConstraints
设置self.bottomSpacingConstraint
之前,我仍然得到一个CGRectZero
返回框架。 根据objc.io文章(和这个SO答案 ),这些方法应该触发布局并更新框架。
任何人都可以对如何使这一切工作有所启发吗? 我对解决方案感兴趣,并解释了导致调用布局相关方法的原因(例如,看起来在layoutSubviews
中更改现有约束的常量会导致调用setNeedsUpdateConstraints
,然后触发updateConstraints
并导致约束要多次添加)。
我很确定你不能或不应该从updateConstraints
调用layoutIfNeeded
。 更新约束是在布局周期的早期部分,所以我认为它不会产生你想要的效果。
在你的情况下,解决方案是检查layoutSubviews中依赖于帧的约束的constant
属性,如果需要更新,则在那里更新它或调用setNeedsUpdateConstraints
(小心引起循环)。
您已经说过更新约束会触发另一个对updateConstraints
调用 - 这是真的,我认为您正在滥用updateConstraints
- 它是根据视图内容的更改来更新约束。 您应该只添加那些约束(如果它们尚不存在)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.