繁体   English   中英

在自定义视图中使用自动布局,其中约束依赖于框架

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM