总的来说,在 iOS 开发中添加约束有 2 种方式,通过 Interface Builder 的界面拖拽添加,或者手写代码添加。

Interface Builder 实现

在 Interface Builder 下只能通过界面添加,所以无需考虑添加的时机。

代码实现

  1. 初始化的约束设置在 - (void)viewDidLoad 方法中添加
  2. 后期需要修改更新的约束设置则在 - (void)updateConstraints 方法中添加

关于第一点的说法在 WWDC 2015 的 Session 219 - Mysteries of Auto Layout, Part 2 中有提到:

All of your initial constraint setup should ideally happen inside Interface Builder.
Or if you really find that you need to allocate your constraints programmatically, some place like viewDidLoad is much better.

第二点的说法则在 - (void)updateConstraints文档中有提到:

Override this method to optimize changes to your constraints.
……
Your implementation must be as efficient as possible. Do not deactivate all your constraints, then reactivate the ones you need. Instead, your app must have some way of tracking your constraints, and validating them during each update pass. Only change items that need to be changed. During each update pass, you must ensure that you have the appropriate constraints for the app’s current state.

大概的意思就是当需要修改约束时,保留待修改的约束的引用,在该方法中的合适时机进行修改。

注意事项

若全部的约束都是写在 - (void)updateConstraints 方法中的话,需要额外设置 UIViewrequiresConstraintBasedLayout 属性为 YES
因为当代码全部写在 - (void)updateConstraints 方法中时,系统是不知道当前 View 是否采用约束的方式来布局,所以就不会调用 - (void)updateConstraints 方法,所以为了解决「先有鸡还是先有蛋」的问题,把 requiresConstraintBasedLayout 属性设置为 YES,以告诉系统该 View 采用约束的方式来布局。
这个比较坑,在文档中并没有提及到,但是在 UIView 的头文件(打开 Xcode,按下快捷键「⇧⌘O」后,输入 requiresConstraintBasedLayout)中可以找到:

constraint-based layout engages lazily when someone tries to use it (e.g., adds a constraint to a view). If you do all of your constraint set up in -updateConstraints, you might never even receive updateConstraints if no one makes a constraint. To fix this chicken and egg problem, override this method to return YES if your view needs the window to use constraint-based layout.

参考