何谓更新约束?个人以为即在添加了基本约束之后,UI交互过程中,需要改变原来的基本约束,谓之更新约束。
一个简单的例子,主界面上有一个红色的视图,它的尺寸是100x100,中心点与主视图重合。当单击该视图时,其尺寸以一定的比例不断放大,但是其宽不能超过主视图的宽,同样,其高不能超过主视图的高。
注意:官方的例子中,是用一个button做演示的,但是无论是直接运行官方的代码或者我自己重新写的代码,都无法达到预期的效果。使用UI View之后,则有了效果。暂时不知道原因何在。
在基本布局的例子中,我们把添加约束的代码写在了视图的初始化函数中,约束起到了其应有的作用。这里,由于我们要随着点击不断更新约束,因此我们将约束写在UIView的重载函数updateConstraints中,这也是苹果推荐的添加和更新约束的地方:
// this is Apple's recommended place for adding/updating constraints
- (void)updateConstraints {
[self.growingButton updateConstraints:^(MASConstraintMaker *make) {
make.center.equalTo(self);
make.width.equalTo(@(self.buttonSize.width)).priorityLow();
make.height.equalTo(@(self.buttonSize.height)).priorityLow();
make.width.lessThanOrEqualTo(self);
make.height.lessThanOrEqualTo(self);
}];
//according to apple super should be called at end of method
[super updateConstraints];
}
单击视图的响应代码如下:
- (void)didTapGrowButton:(UIButton *)button {
self.buttonSize = CGSizeMake(self.buttonSize.width * 1.3, self.buttonSize.height * 1.3);
// tell constraints they need updating
[self setNeedsUpdateConstraints];
// update constraints now so we can animate the change
[self updateConstraintsIfNeeded];
[UIView animateWithDuration:0.4 animations:^{
[self layoutIfNeeded];
}];
}
另外,我们还要重写一个类方法:
+ (BOOL)requiresConstraintBasedLayout
{
return YES;
}
苹果对于该方法又一个说明:
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.
基于约束的布局是懒触发的,只有在添加了约束的情况下,系统才会自动调用updateConstraints方法,如果把所有的约束放在 updateConstraints中,那么系统将会不知道你的布局方式是基于约束的,所以重写requiresConstraintBasedLayout 返回YES就是明确告诉系统:虽然我之前没有添加约束,但我确实是基于约束的布局!这样可以保证系统一定会调用 updateConstraints 方法 从而正确添加约束.
我的个人理解:如果不重写requiresConstraintBasedLayout 并返回YES,可能造成updateConstraints不被调用,这样你写的约束也就不会生效。