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
  • 相关阅读:
    [转发]深入理解git,从研究git目录开始
    iOS系统网络抓包方法
    charles抓包工具
    iOS多线程中performSelector: 和dispatch_time的不同
    IOS Core Animation Advanced Techniques的学习笔记(五)
    IOS Core Animation Advanced Techniques的学习笔记(四)
    IOS Core Animation Advanced Techniques的学习笔记(三)
    IOS Core Animation Advanced Techniques的学习笔记(二)
    IOS Core Animation Advanced Techniques的学习笔记(一)
    VirtualBox复制CentOS后提示Device eth0 does not seem to be present的解决方法
  • 原文地址:https://www.cnblogs.com/yecong/p/6708104.html
Copyright © 2011-2022 走看看