使用 masonry mas_updateConstraints 的 時候 須要注意的事項

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); }];
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

這是基類裏對textlabel的佈局,其相對view自己居中顯示,而子類裏想改變這種佈局方式,改爲和另一個button對齊顯示,所以我就在子類裏調整佈局以下:ios

# 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:git

# 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 這裏是一個新的約束 
源碼裏有個方法是對是不是同一個約束的判斷: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; }
  • 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仍是從新添加了一個約束。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); }];
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
 
2
相關文章
相關標籤/搜索