自动布局和程序约束:如何处理多次触发的 updateConstraints? [英] Autolayout & programmatic constraints: How to deal with updateConstraints firing multiple times?

查看:19
本文介绍了自动布局和程序约束:如何处理多次触发的 updateConstraints?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当以编程方式创建布局时,我遵循 Apple 的建议:覆盖 -updateConstraints,添加自定义约束,并在将子视图添加到视图后调用 -setNeedsUpdateConstraints.我的典型设置如下所示:

When programmatically creating layouts, I follow Apple's advice: override -updateConstraints, add custom constraints, and call -setNeedsUpdateConstraints once subviews have been added to the view. My typical setup looks like this:

- (void)setupViews
{
    //Style View

    //Add gesture recognizers

    //Add Subviews


    [self setNeedsUpdateConstraints];
}

- (void)updateConstraints
{
    //Add custom constraints       

    [super updateConstraints];
}

问题

在某些情况下 -updateConstraints 会被多次触发(例如,当视图的控制器被呈现或推送时带有动画).这里的问题是添加的每个约束都会重新添加.当尝试按需更改添加约束的常数时,这将成为一个严重的问题,因为有两个原始约束随后会相互冲突.我想,即使您在创建约束后没有对其进行操作,也会使您看起来不太好.

There are occasions when -updateConstraints gets fired multiple times (for example, when a view's controller is presented or pushed w/ animation). The problem here is that each constraint added gets re-added. This becomes a serious problem when trying to on-demand change the constant of an added constraint, since there are two of the original constraint that subsequently conflict with each other. I imagine that even when you aren't manipulating the constraints after creating them, having double what you doesn't seem good.

可能的解决方案

1 - 在 -updateConstraints 中应用之前移除所有影响视图的约束:

1 - Remove all constraints effecting the view before applying them in -updateConstraints:

 - (void)updateConstraints
    {   
        //Remove all constraints affecting view & subviews

        //Add custom constraints

        [super updateConstraints];       
    }

2 - 设置布局标志 &在添加自定义约束之前检查它:

2 - Set a layout flag & check against it before adding custom constraints:

- (void)updateConstraints
{
    if (self.didAddConstraints) {
        [super updateConstraints];
        return;
    }

    //Add custom constraints   

    self.didAddConstraints = YES;    

    [super updateConstraints];
}

3 - 不必担心加倍约束,并且每当需要更改常量时,只需在重新添加之前删除该约束即可.

3 - Don't worry about doubling up on constraints, and whenever changing a constant is needed, only remove that constraint before re-adding.

3 - 我没想到的很棒的东西.

3 - Something awesome that I haven't thought of.

这里的最佳做法是什么?

What's the best practice here?

推荐答案

简答:潜在解决方案编号 2.

Short answer: Potential solution number 2.

随着布局变得越来越复杂,删除和重新应用所有约束可能会变得昂贵.此外,如果你的布局是有状态的,你会遇到更多的问题.

Removing and reapplying all constraints may become costly as the layout becomes more complex. Besides, if your layout is stateful, you'd have more problems.

加倍约束非常低效,你永远无法知道 updateConstraints 可能会被调用多少次.

Doubling constraints is very inefficient, you can never know how many times updateConstraints might be called.

正如 这篇博文 所示,使用标志是处理这个问题的最简单、最有效的方法.我自己就是这样处理的.

As this blog post shows, using a flag is the simplest, most efficient way of dealing with this problem. That is how I deal with it myself.

作为旁注,您提到存在一种您尚未想到的很棒的方式.大多数时候,最简单的方法是最棒的方法.:)

As a side note, you mention of there existing an awesome way that you have not thought of yet. Most of the times, the simplest way IS the most awesome way. :)

这篇关于自动布局和程序约束:如何处理多次触发的 updateConstraints?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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