Masonry就不作过多的介绍了,搞iOS布局的应该都知道这个开源库,使用它能节省很多体力,最近在项目中使用这个库的mas_updateConstraints时,发现该方法和本身想象的有点不同。先贴下本身的代码:python
# 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); }];
这是基类里对textlabel的布局,其相对view自己居中显示,而子类里想改变这种布局方式,改为和另一个button对齐显示,所以我就在子类里调整布局以下:ios
# SubClass [self.textLabel mas_updateConstraints:^(MASConstraintMaker *make) { make.centerY.equalTo(self.checkedButton.mas_centerY); }];
本觉得这么作Masonry会帮我把centerY的布局更新,可是编译运行时会提示存在冲突,有两个centerY布局约束,不知道该使用哪个,而后我就读了下Masonry的源码,发现原来mas_updateConstraints方法里对同一个布局的理解就是相对的元素也是一致才行,即这里这样作才算一次update:git
# SubClass [self.textLabel mas_updateConstraints:^(MASConstraintMaker *make) { make.centerY.equalTo(self.mas_centerY).offset(10); }];
因此,这里的一个update是针对以下这种情形才行:
A->B A->B的变化
A->C 这里是一个新的约束
源码里有个方法是对是不是同一个约束的判断:github
- (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; }
能够看到,须要firstItem,secondItem,firstAttribute,secondAttribute,relation,multiplier,priority等一致才会当作同一个约束,不然都不算作一个约束。因此在使用mas_updateConstraints时你们必定要分清楚是否update仍是从新添加了一个约束。markdown
PS:针对我遇到的这种使用状况,我在基类里将个人居中约束设置了一个优先级来处理的less
# 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); }];