zoukankan      html  css  js  c++  java
  • 使用 masonry mas_updateConstraints 的 时候 需要注意的事项

    Masonry就不做过多的介绍了,搞iOS布局的应该都知道这个开源库,使用它能节省不少体力,最近在项目中使用这个库的mas_updateConstraints时,发现该方法和自己想象的有点不一样。先贴下自己的代码:

    # BaseClass
     [_textLabel mas_makeConstraints:^(MASConstraintMaker *make) {
        self.textLabelLeftLayout = make.left.equalTo(self.checkedButton.mas_right);
        make.centerY.equalTo(self.mas_centerY);
        make.height.mas_equalTo(checkBoxWidth);
        make.right.lessThanOrEqualTo(self.mas_right);
    }];
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    这是基类里对textlabel的布局,其相对view本身居中显示,而子类里想改变这种布局方式,改成和另外一个button对齐显示,因此我就在子类里调整布局如下:

    # SubClass
      [self.textLabel mas_updateConstraints:^(MASConstraintMaker *make) {
          make.centerY.equalTo(self.checkedButton.mas_centerY);
      }];
    • 1
    • 2
    • 3
    • 4
    • 1
    • 2
    • 3
    • 4

    本以为这么做Masonry会帮我把centerY的布局更新,但是编译运行时会提示存在冲突,有两个centerY布局约束,不知道该使用哪一个,然后我就读了下Masonry的源码,发现原来mas_updateConstraints方法里对同一个布局的理解就是相对的元素也是一致才行,即这里这样做才算一次update:

    # SubClass
      [self.textLabel mas_updateConstraints:^(MASConstraintMaker *make) {
          make.centerY.equalTo(self.mas_centerY).offset(10);
      }];
    • 1
    • 2
    • 3
    • 4
    • 1
    • 2
    • 3
    • 4

    所以,这里的一个update是针对如下这种情形才行: 
    A->B A->B的变化 
    A->C 这里是一个新的约束 
    源码里有个方法是对是否是同一个约束的判断:

    - (MASLayoutConstraint *)layoutConstraintSimilarTo:(MASLayoutConstraint *)layoutConstraint {
        // check if any constraints are the same apart from the only mutable property constant
    
        // go through constraints in reverse as we do not want to match auto-resizing or interface builder constraints
        // and they are likely to be added first.
        for (NSLayoutConstraint *existingConstraint in self.installedView.constraints.reverseObjectEnumerator) {
            if (![existingConstraint isKindOfClass:MASLayoutConstraint.class]) continue;
            if (existingConstraint.firstItem != layoutConstraint.firstItem) continue;
            if (existingConstraint.secondItem != layoutConstraint.secondItem) continue;
            if (existingConstraint.firstAttribute != layoutConstraint.firstAttribute) continue;
            if (existingConstraint.secondAttribute != layoutConstraint.secondAttribute) continue;
            if (existingConstraint.relation != layoutConstraint.relation) continue;
            if (existingConstraint.multiplier != layoutConstraint.multiplier) continue;
            if (existingConstraint.priority != layoutConstraint.priority) continue;
    
            return (id)existingConstraint;
        }
        return nil;
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    可以看到,需要firstItem,secondItem,firstAttribute,secondAttribute,relation,multiplier,priority等一致才会当做同一个约束,否则都不算做一个约束。所以在使用mas_updateConstraints时大家一定要分清楚是否update还是重新添加了一个约束。


    PS:针对我遇到的这种使用情况,我在基类里将我的居中约束设置了一个优先级来处理的

    # BaseClass
     [_textLabel mas_makeConstraints:^(MASConstraintMaker *make) {
        self.textLabelLeftLayout = make.left.equalTo(self.checkedButton.mas_right);
        make.centerY.equalTo(self.mas_centerY).priorityMedium();
        make.height.mas_equalTo(checkBoxWidth);
        make.right.lessThanOrEqualTo(self.mas_right);
    }];
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
     
    2
  • 相关阅读:
    1096 Consecutive Factors (20分)
    js-实现省市区地址选择器三级联动
    js-面向对象编程基础
    js-滑块拼图登录验证
    js-promise以及async、await实现简易红绿灯
    js-前端分页效果的实现
    js-ajax方法详解以及封装
    js-jsonp跨域请求原理以及jsonp的封装
    js-实现常见的拖拽效果(表单滑块验证)
    js本地存储-localStorage和cookie详解以及区别
  • 原文地址:https://www.cnblogs.com/yecong/p/6708104.html
Copyright © 2011-2022 走看看