mas_makeConstraints & mas_updateConstraints & mas_remakeConstraints

先简单介绍一下,这几个方法的使用场景

mas_makeConstraints : 一个视图,刚创建出来,没有任何约束。用这个方法,给视图创建 x,y,w,h的约束。
mas_updateConstraints : 一个视图,之前已经有约束了,因为条件变了,需要变位置(x,y),变宽高(w,h),需要修改约束。
mas_remakeConstraints : 一个视图,之前有约束,但之前的约束,全都不要了(x,y,w,h),需要全部重新创建。


重点说明 mas_updateConstraints

mas_updateConstraints 使用场景是,某个视图之前已经有 x,y,w,h 约束了。
现在因为某些原因,需要修改某个约束。
比如修改位置 x, y。
修改宽高 w,h。

但是,mas_updateConstraints 是一直都有效的吗?

场景一

两个 view。橙色的 view,是父视图。
紫色的 view 是子视图。

15295688808788.jpg
UIView *testView = [[UIView alloc] init];
    testView.backgroundColor = [UIColor orangeColor];
    [self.view addSubview:testView];
    [testView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.top.offset(20);
        make.height.width.offset(200);
    }];
    
    _testView = testView;
    
    
    UIView *test2View = [[UIView alloc] init];
    test2View.backgroundColor = [UIColor purpleColor];
    [testView addSubview:test2View];
    [test2View mas_makeConstraints:^(MASConstraintMaker *make) {
         make.left.top.offset(20); // x,y 依赖于父容器
        make.height.offset(100); // width 和父容器没有一毛钱关系
        make.width.offset(100); // height 和父容器没有一毛钱关系
    }];
    
    _testView2 = test2View;

testView2 是子容器,约束设置的条件是 ,除了 x,y 和父容器有关系之外(也不可能没有关系)
width & height 都写的是常量,和父容器没有任何关系。

touchesBegan 测试 mas_updateConstraints,来修改 testView2 的 width,height。
(这个宽高和父容器没有一毛钱关系)

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    [_testView2 mas_updateConstraints:^(MASConstraintMaker *make) {
        make.width.offset(150);
        make.height.offset(150);
    }];
}

运行结果:

15295690812429.jpg

查看控制台,非常干净,没有报约束冲突的问题。

15295691064947.jpg

场景二

还是两个 view。橙色的 view,是父视图。
紫色的 view 是子视图。

15295693759982.jpg
    testView.backgroundColor = [UIColor orangeColor];
    [self.view addSubview:testView];
    [testView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.top.offset(20);
        make.height.width.offset(200);
    }];
    
    _testView = testView;
    
    
    UIView *test2View = [[UIView alloc] init];
    test2View.backgroundColor = [UIColor purpleColor];
    [testView addSubview:test2View];
    [test2View mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.top.offset(20); // x,y 依赖于父容器
        
        make.height.equalTo(testView).multipliedBy(0.5);// width 和父容器有关系了,它是父容器宽度的一半
        make.width.equalTo(testView).multipliedBy(0.5); // height 和父容器有关系了,它是父容器高度的一半
        
//        make.height.offset(100); // width 和父容器没有一毛钱关系
//        make.width.offset(100); // height 和父容器没有一毛钱关系
       
    }];

    _testView2 = test2View;

现在 testView2width & height 也是约束设置的,但是已经和父容器建立关系了。
它们分别是父容器宽高的一半。

现在在使用 mas_updateConstraints 来更新testView2的宽高约束。

[_testView2 mas_updateConstraints:^(MASConstraintMaker *make) {
        make.width.offset(150);
        make.height.offset(150);
    }];

运行结果:

15295693759982.jpg

testVIew2使用mas_updateConstraints 并没有成功的修改自己的宽高(因为和父容器建立了关系了)

在来看看控制台输出:

15295694471885.jpg

很不幸的是,控制台报出了约束异常。
mas_updateConstraints 好像,并不是万能的?
不是一句简单的 更新视图的约束就能说明白的。

那如何去修正呢?

修正步骤:

  1. 记录和父容器产生了关系的约束对象。
  2. 更新这些约束对象之前,先把之前的约束对象卸载。

声明两个约束对象,width & height

MASConstraint *_heightConstraint; // 子视图宽度约束
MASConstraint *_widthConstraint; // 子视图高度约束

记录和父容器产生了关系的约束对象

_heightConstraint = make.height.equalTo(testView).multipliedBy(0.5);
_widthConstraint = make.width.equalTo(testView).multipliedBy(0.5);

在更新这些和父视图建立了关系的约束之前,必须先卸载之前的约束对象。
然后再使用 mas_updateConstraints 更新全新的约束

  - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    [_widthConstraint uninstall]; // 先卸载之前的宽度约束(multipliedBy)
    [_heightConstraint uninstall]; // 先卸载之前的高度约束(multipliedBy)
    [_testView2 mas_updateConstraints:^(MASConstraintMaker *make) {
        make.width.offset(150);
        make.height.offset(150);
    }];
}

运行结果:

15295698322527.jpg

再看看看控制台:

15295698660922.jpg

非常干净。没有报任何冲突。

当然还有 centerX,centerY 位置相关的(x,y不冲突,不代表 centerX,centerY 不冲突)等约束,大家可以自己做测试看看。


最后结论:

  1. mas_updateConstraints 并是一个简单的更新视图约束就能说明白的。
  2. 某些和父亲容器建立了约束关系的约束,在使用 mas_updateConstraints 之前,必须先卸载之前的约束。
  3. 对于子视图的 x,y 约束,使用mas_updateConstraints,总是有效的。(有人会说,x,y 也和父视图建立了关系了呀?那你能找一个 x,y 和父视图没有建立关系的约束吗?)
  4. 对于父视图是控制器根 view 的情况下,mas_updateConstraints。这是因为根 view 的大小基本都是定死的。
  5. 当使用mas_updateConstraints遇到约束问题时,可以先想想,是哪些约束事先需要删除但没有删除的?

一个比较暴力的解决 在使用 mas_updateConstraints 出现约束冲突的问题方法。

更新哪个约束出冲突了,就把哪个约束删除了,在更新。也省的去研究,为什么会出冲突了。
约束本身就是个比较蛋疼的东西。

你可能感兴趣的:(mas_makeConstraints & mas_updateConstraints & mas_remakeConstraints)