使用 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

posted on   举个例子yi聪聪  阅读(9669)  评论(0编辑  收藏  举报

编辑推荐:
· 开发中对象命名的一点思考
· .NET Core内存结构体系(Windows环境)底层原理浅谈
· C# 深度学习:对抗生成网络(GAN)训练头像生成模型
· .NET 适配 HarmonyOS 进展
· .NET 进程 stackoverflow异常后,还可以接收 TCP 连接请求吗?
阅读排行:
· 本地部署 DeepSeek:小白也能轻松搞定!
· 基于DeepSeek R1 满血版大模型的个人知识库,回答都源自对你专属文件的深度学习。
· 在缓慢中沉淀,在挑战中重生!2024个人总结!
· 大人,时代变了! 赶快把自有业务的本地AI“模型”训练起来!
· Tinyfox 简易教程-1:Hello World!
< 2025年2月 >
26 27 28 29 30 31 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 1
2 3 4 5 6 7 8

导航

统计

点击右上角即可分享
微信分享提示