在代码中修改故事板自动布局约束的最佳实践?

时间:2014-01-08 23:03:59

标签: ios autolayout uistoryboard

我总是在代码中完成我的用户界面,但已经决定我应该为当前项目使用故事板和自动布局。一切都进展顺利,直到我构建了一个复杂的场景,其中包含大约50个具有大量层次结构和一些视图网格的视图。

问题是我的自动布局在某些设备和方向上变得混乱。我发现使用IB尝试修复数十(数百?)个约束或追踪问题并解决问题具有挑战性。情况是这样的,我没有得到错误或警告,有时只是一些不愉快的布局。对于追踪约束信息,你需要做的所有点击和更改设置都会让IB变得很痛苦,更不用说完全了解它们在场景中的相关性。

我花了一天时间阅读有关自动布局和约束的文档和背景资料,看来我最好的解决方案是使用可视化格式在代码中指定约束并创建一些自定义代码来帮助。但是,我似乎无法找到有关如何从IB转换为代码的任何内容。

具体来说,我应该擦除所有IB约束并手动完成它们还是可以选择性?我问,因为我在包含内容视图具有完美布局的视图中有一些视图组。

其次,我最好把代码放在哪里?我想共存故事板,只想有选择地修改一些复杂的场景。是视图控制器的viewWillAppear:修改或删除/添加它控制的视图的约束的正确位置?

3 个答案:

答案 0 :(得分:9)

将您希望能够在storyboard / xib文件中修改的NSLayoutConstraint的IBOutlet连接到控制器/视图类。

连接布局对象后,您可以修改.constant属性并为视图设置动画:

[self.containerView layoutIfNeeded]; //make sure all layout operations are done
self.containerViewBottomLayoutConstraint.constant = 200.0; //change the layout
[UIView animateWithDuration:duration animations:^{
    [self.containerView layoutIfNeeded]; //animate the changes
}];

已更新:您可以在viewDidLoad,awakeFromNib,viewDidAppear或基于事件的情况下添加修改代码。这实际上取决于你的意图。

答案 1 :(得分:5)

很抱歉,在其他项目入侵的情况下,这么长时间才能回到这一点。

我不得不做很多重构来简化我的场景,以便自动布局可以做正确的事情,但我对结果并不完全满意。问题似乎是IB不容易使用大量项目,并且必要时自动布局很复杂。

据说,到目前为止我看到的最好成绩来自Justin Driscoll的这篇文章:http://themainthread.com/blog/2014/02/building-a-universal-app.html

他主张构建自定义视图以封装可重用的UI组件。我已经采用了这种方法,但已经扩展了这个想法,以便捆绑相关的组件,这些组件在布局更改时不会以非常不同的方式进行布局。例如,我有一个带按钮和两个标签的进度条,所以即使我没有将它们作为一个组重复使用,它们也需要相邻并且在概念上是相关的,所以我为它们制作了一个自定义视图来处理自动贾斯汀建议的布局。

我现在采取的方法是每个级别的自动布局应该只有少数几个元素。如果一个级别太复杂,我会在自定义视图中捆绑一些相关项目,并在该新视图中推送一些自动布局。到目前为止还不错。

答案 2 :(得分:2)

使用那么多视图时,自动布局真的很棘手。我使用了类似的复杂视图结构,我发现最好尽量保留代码或IB中的所有约束。现在我们将他们留在IB。我们将约束移动到代码中的唯一时间是当我们支持不同的屏幕大小时,我们需要修改单个约束以使视图正常工作。我一直在viewDidLoad中修改约束。

当某些事情搞砸的时候,我几乎总是必须在该视图上查看所有约束并重新开始。它很糟糕,但它通常比追踪问题更快。我们做的一件事就是更容易处理这类事情,就是将.xibs与故事板一起使用。这样,每个视图都可以处理它自己的布局,你可以将它拉到一个位于故事板中的视图中。