转载

如何组织 Auto Layout 代码

作者:dom,原文链接: Where To Put The Auto Layout Code ,原文日期:2015/08/12

译者: SergioChan ;校对: Shanks ;定稿: 小锅

Auto Layout是一件很神奇的事情。像一个巫师一样告诉元素应该去什么位置并且让他们守规矩。你并不需要亲自将元素放到那些位置去。感觉像是天地因为你的咒语而将他们移动了。

但是你应该在什么时候念“咒语”呢?换句话说,当你没有使用界面生成器(Interface Builder)的时候,你应当把Auto Layout的代码放在哪呢?

UIView 的方法 updateConstraints 的文档我们可以看到:

设置自定义视图约束需要通过重载这个方法来完成。

因为有这句话,我总是认为苹果是在要求我把布局的代码放到这个方法里。那么问题就来了:这个方法会被 UIKit 调用至少两次,重复添加相同的约束就会导致错误。我在网上找到的最佳途径是在视图类中添加一个布尔值的属性,并且在 updateConstraints() 去赋值,这样就可以保证你只运行了一次布局的代码。

文档里还写到:

当你的自定义视图发现有一个属于它的约束忽然失效了,它会马上移除这个约束,然后调用 setNeedsUpdateConstraints 来告知视图它的约束需要被更新。

这就意味着 updateConstraints() 应该在视图中的约束因为某些事件而改变的情况下使用。而且这个方法的名字在这个场景下也更加的有意义。

在我的几乎所有的布局中约束都是固定的。当然,有些事情我也需要改变一个约束中的常量。我可以无需移除并重新添加这个约束。( NSLayoutConstraint 中的常量是它在被创建之后唯一能被修改的东西了。)

正因为此,我开始将布局代码都放到 init(frame:) 里去。但是有了上面文档提到的那些内容。我还是觉得不太适应。

后来在今年的 WWDC 上,有一个苹果的工程师就是建议这么做的。而且就在昨天,我收到了一个关于 updateConstraints() 没有被调用的问题的回复 —— 至少我称之为 bug。结果我发现它并不是一个bug。

苹果工程师这么写道:

总的来说,如果约束只会被创建一次,它就应该被放在初始化方法中完成,例如 -init 或者 -viewDidLoad 等等。留着 updateConstraints 给那些在程序运行时可能改变的布局。

不错。当我对于代码的感觉被苹果推荐的时候,我挺享受的。

这里 有一个示例,里面你能看到我把布局代码放在哪里了。

写布局的同志们加油吧!

对了,如果你喜欢这篇文章,请关注我的 feed 。

更新:Ole Begemann 在他的博客中写了一篇 When should you implement updateConstraints 。

如何组织 Auto Layout 代码
正文到此结束
Loading...