美文网首页IOS
mas_makeConstraints & mas_update

mas_makeConstraints & mas_update

作者: 人话博客 | 来源:发表于2018-06-21 16:40 被阅读0次

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

    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<UITouch *> *)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<UITouch *> *)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_update

        本文链接:https://www.haomeiwen.com/subject/xlhcyftx.html