MASConstraint的存在就是為了創建鏈式語法的目的,Constraint可以代表單一的NSLayoutConstraint對象(子類MASViewConstraint),也可以代表一組NSLayoutConstraints(子類MASComposisteConstraint)
在篇一MASConstraintMake的分析,我們初步的提到了MASConstraint,本篇詳細的討論一下
第一部分 MASConstraint和他的子類###
1、MASConstraint
??前面說過MASConstraint的存在就是為了創建鏈式語法的目的,他除了提供基礎的屬性,支持鏈式語法,同時和MASCompositeConstraint、MASViewConstraint共同發揮作用。
2、MASCompositeConstraint
??make.edges、make.size、make.center等返回的就是MASCompositeConstraint類型;舉個例子:
make.edges.mas_equalTo(UIEdgeInsetMake(10,10,10,10))
MASCompositeConstraint有一個屬性,NSMutableArray類型的,存放的是MASViewConstraint類型的對象,在布局的時候,會遍歷這個數組,逐一在進行install方法的調用(參見第一篇文章);make.edges返回的就是MASCompositeConstraint類型。
3、MASViewConstraint
??MASViewConstraint是承載支持AutoLayout真正的對象,它包含了創建一個NSLayoutConstraint的必要屬性,并且把它添加到對應的view上。我們可以看到MASViewConstraint的兩個屬性:
@property (nonatomic, strong, readonly) MASViewAttribute *firstViewAttribute;
@property (nonatomic, strong, readonly) MASViewAttribute *secondViewAttribute;
這里面要講一下MASViewAttribute類
看一下MASViewAttribute的幾個屬性
@property (nonatomic, weak, readonly) MAS_VIEW *view;
@property (nonatomic, weak, readonly) id item;
@property (nonatomic, assign, readonly) NSLayoutAttribute layoutAttribute;
我們再看一下NSLayoutConstraint的創建
MASLayoutConstraint *layoutConstraint
= [MASLayoutConstraint constraintWithItem:firstLayoutItem
attribute:firstLayoutAttribute
relatedBy:self.layoutRelation
toItem:secondLayoutItem
attribute:secondLayoutAttribute
multiplier:self.layoutMultiplier
constant:self.layoutConstant];
到這個時候,大致就明白了這幾個類的作用了。
第二部分 了解一下常見用法###
1、equalTo
我們還是使用在第一篇中的例子
[view1 mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(superview.mas_top).with.offset(padding.top);
make.left.equalTo(superview.mas_left).with.offset(padding.left);
make.bottom.equalTo(superview.mas_bottom).with.offset(-padding.bottom);
make.right.equalTo(superview.mas_right).with.offset(-padding.right);
}];
我們知道make.top返回的就是MASConstraint對象,準確的說是MASViewConstraint對象。具體如何跟AutoLayout對應起來,在第一篇中已經有介紹了,不再描述。這里面說一下equalTo的用法(greaterThanOrEqualTo等類似)。
我們應該經常能看到如下這些用法:
make.top.equalTo(@(100))</br>
??make.top.equalTo(view1.mas_top)</br>
??make.top.equalTo(view1)</br>
equalTo即可接受NSValue類型的參賽,大概是這幾種:NSNumber、CGPoint、CGSize、UIEdgeInsets等;</br>
??equalTo也可接受UIView型的參數;</br>
??equalTo還可接受MASViewAttribute類型的參數;
NSValue類型的參賽,比對的是superView,例如make.top.equalTo(@(100)),距離superView的頂部100;</br>
??UIView型的參數,比對的是view的相對應的屬性,例如make.top.equalTo(view1),代表和view1的top值是一致的;</br>
??MASViewAttribute類型的參數,比對的是view的制定的屬性,例如make.top.equalTo(view1.mas_top),代表top距離view1的top是一致的;
2、insets、sizeOffset...
- (MASConstraint * (^)(MASEdgeInsets insets))insets;
- (MASConstraint * (^)(CGSize offset))sizeOffset;
- (MASConstraint * (^)(CGPoint offset))centerOffset;
- (MASConstraint * (^)(CGFloat offset))offset;
- (MASConstraint * (^)(NSValue *value))valueOffset;
我們可以看一下insets的用法
1. make.top.insets(UIEdgeMake(10,20,30,40))
它實際上只會取edge的top部分,其他的值怎么設置都不會影響視圖的位置
2. make.edges.insets(UIEdgeMake(10,20,30,40))
這樣取的就是整個的edge
實現這個的區別,根據源碼分析,就是MASCompositeConstraint的作用;因為top返回的是MASViewConstraint類型,只會匹配對應的layoutAttribute的值,但是edges返回的是MASCompositeConstraint對象,對MASCompositeConstraint對象調用insets方法,它會逐一的遍歷它持有的viewConstraint對象(這里也就是top、left、right、bottom),然后相應的一一去在UIEdgeMake中尋找對應匹配的值。詳細實現見源碼。
其他的用法大同小異,offset有一些差異,直接接受的是CGFloat類型,制定的是一個單一的值,valueOffset接收的是value類型,可以傳遞number、CGSize等。
3、left、top、...
- (MASConstraint *)left;
- (MASConstraint *)top;
- (MASConstraint *)right;
- (MASConstraint *)bottom;
- (MASConstraint *)leading;
- (MASConstraint *)trailing;
- (MASConstraint *)width;
- (MASConstraint *)height;
- (MASConstraint *)centerX;
- (MASConstraint *)centerY;
- (MASConstraint *)baseline;
對,你沒看錯,出了對maker可調用這些方法,對調用這些方法返回的MASConstraint也可以調用這些方法。
也就是這樣的用法:
make.top.left.right...
對MASConstraint調用top、left返回的是MASCompositeConstraint對象,比如:
make.centerX.centerY等同于make.center
make.left.top.right.bottom等同于make.edges
make.width.height等同于make.size
具體原理,下節分析。
4、其他...
剩下的比較簡單,一筆帶過
priorityLow等一系列的代表優先級
multipliedBy等就是跟NSLayoutConstraint創建的倍數參數同樣的東西
with和and可以忽略,因為這兩個直接返回self,純粹語義上的修飾作用
install和uninstall很明顯
mas_equalTo等可以指定數值型為參數,會被NSValue自動封箱,跟equalTo實際是一回事