在自定义视图中使用自动布局,其中的约束依靠框架 [英] Using auto-layout in a custom view where constraints rely on frame

查看:128
本文介绍了在自定义视图中使用自动布局,其中的约束依靠框架的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在写编程方式初始化的自定义视图。我重写 updateConstraints添加所有该视图所需要的约束。

I'm writing a custom view that is initialized programmatically. I override updateConstraints to add all the constraints required for this view. :

- (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 被调用。它还提到

The problem is that self.bounds returns the equivalent of CGRectZero. I did my research and according to this objc.io article, that's expected as the frame doesn't get set until layoutSubviews is called. It also mentions

要强制系统立即更新视图树的布局,你可以叫 layoutIfNeeded / layoutSubtreeIfNeeded ( iOS和OS分别为X)。这可能是有益的,如果你的下一个步骤依靠的意见帧是最新的。

To force the system to update the layout of a view tree immediately, you can call layoutIfNeeded/layoutSubtreeIfNeeded (on iOS and OS X respectively). This can be helpful if your next steps rely on the views’ frame being up to date.

然而,当我添加

[self setNeedsLayout];
[self layoutIfNeeded];

就在 updateConstraints 设置 self.bottomSpacingConstraint 之前,我还是得到了 CGRectZero 回帧。按照objc.io文章(这 SO回答),这些方法应该触发布局和更新框架。

right before setting self.bottomSpacingConstraint in updateConstraints, I still get a CGRectZero back for the frame. According to the objc.io article (and this SO answer), these methods should trigger layout and update the frame.

任何人都可以照如何使这所有的工作一些启示?我感兴趣的解决方案,以及是什么原因导致其布局相关的方法被称为解释(例如,看来,改变现有的约束常数在 layoutSubviews 导致 setNeedsUpdateConstraints 来调用,然后触发 updateConstraints 并导致约束添加多次)。

Can anybody shine some light on how to make this all work? I'm interested in the solution as well as an explanation of what causes which layout-related methods to be called (for example, it appears that changing an existing constraint's constant in layoutSubviews causes setNeedsUpdateConstraints to be called, which then triggers updateConstraints and causes constraints to be added multiple times).

推荐答案

我是pretty确保您不能或不应该调用 layoutIfNeeded updateConstraints 。更新的约束是在布局周期的早期部分,所以我不认为这会有你所追求的效果。

I'm pretty sure that you can't, or shouldn't, call layoutIfNeeded from updateConstraints. Updating the constraints is in an earlier part of the layout cycle, so I don't think it will have the effect you are after.

在您的情况下,解决办法是检查layoutSubviews你的框架依赖约束的属性,如果需要更新,无论有或致电更新 setNeedsUpdateConstraints (小心造成循环)。

In your case the solution would be to check the the constant property of your frame-dependent constraint in layoutSubviews, and if it needs updating, either update it there or call setNeedsUpdateConstraints (be careful about causing loops).

您已经说过更新约束触发另一个调用 updateConstraints - 这是真的,我想你是滥用 updateConstraints - 它是的更新的基础上更改您的视图的内容限制。您只应添加这些约束,如果他们不存在。

You've said updating the constraint triggers another call to updateConstraints - this is true, and I think you are misusing updateConstraints - it is for updating constraints based on changes to your view's content. You should only be adding those constraints if they don't already exist.

这篇关于在自定义视图中使用自动布局,其中的约束依靠框架的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆