Masonry学习之更新约束

何谓更新约束?个人以为即在添加了基本约束之后,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不被调用,这样你写的约束也就不会生效。

你可能感兴趣的:(Masonry)