第三方 Masonry約束的使用

第三方 Masonry約束的使用 less

給Autolayout披上一層漂亮的外衣以後,將其稱爲Masonry,但Masonry的本質仍是Autolayout。能夠理解爲Masonry是對Autolayout的封裝.ide

對於一個約束。他實際表示的是一個不等或者相等關係atom

 

用Masonry建立一個完整的約束應該是這樣的spa

//view1的左邊距離父View左邊10個點:
[view1 mas_makeConstraints:^(MASConstraintMaker *make) {
    make.left.equalTo(view1.superview.mas_left).multipliedBy(1).offset(10);
}];

Attribute

MASConstraintMaker

上面的表達式中,咱們能夠看到,make是MASConstraintMaker類型。MASConstraintMaker給咱們提供了22種Attribute類型.net

 

//Basic Attribute
@property (nonatomic, strong, readonly) MASConstraint *left;
@property (nonatomic, strong, readonly) MASConstraint *top;
@property (nonatomic, strong, readonly) MASConstraint *right;
@property (nonatomic, strong, readonly) MASConstraint *bottom;
@property (nonatomic, strong, readonly) MASConstraint *leading;
@property (nonatomic, strong, readonly) MASConstraint *trailing;
@property (nonatomic, strong, readonly) MASConstraint *width;
@property (nonatomic, strong, readonly) MASConstraint *height;
@property (nonatomic, strong, readonly) MASConstraint *centerX;
@property (nonatomic, strong, readonly) MASConstraint *centerY;
@property (nonatomic, strong, readonly) MASConstraint *baseline;

//Margin Attribute
@property (nonatomic, strong, readonly) MASConstraint *leftMargin;
@property (nonatomic, strong, readonly) MASConstraint *rightMargin;
@property (nonatomic, strong, readonly) MASConstraint *topMargin;
@property (nonatomic, strong, readonly) MASConstraint *bottomMargin;
@property (nonatomic, strong, readonly) MASConstraint *leadingMargin;
@property (nonatomic, strong, readonly) MASConstraint *trailingMargin;
@property (nonatomic, strong, readonly) MASConstraint *centerXWithinMargins;
@property (nonatomic, strong, readonly) MASConstraint *centerYWithinMargins;

//Convenient Attribute
@property (nonatomic, strong, readonly) MASConstraint *edges;
@property (nonatomic, strong, readonly) MASConstraint *size;
@property (nonatomic, strong, readonly) MASConstraint *center;

 

Attribute整體來講分爲三大類code

  1. Basic Attribute: 基本屬性,支持到iOS6,通常使用得比較多
  2. Margin Attribute: 邊緣相關屬性,支持到iOS8。因爲版本要求比較高,通常用得比較少。
  3. Convenient Attribute: 便捷屬性,爲了使用方便而特地新增的屬性。Autolayout自己沒有對應的相關屬性

Convenient Attribute實際是基本屬性的組合。好比:edges表示left, right, top, bottom。
下面的兩個代碼實際的意義是同樣的對象

//Convenient Attribute
make.edges.insets(edge);

//Basic Attribute
make.left.right.top.bottom.insets(edge);

 

MASConstraint

前面咱們看到MASConstraintMaker中全部的Attribute都是MASConstraint類型。對於多個Attribute一塊兒寫的表達式:blog

make.left.right.top.bottom.insets(edge);

make.left返回的已是MASConstraint類型,也就是說right這個Attribute是MASConstraint的屬性。
MASConstraint給咱們提供了19種Attribute:接口

 

 
//Basic Attribute @property (nonatomic, strong, readonly) MASConstraint *left; @property (nonatomic, strong, readonly) MASConstraint *top; @property (nonatomic, strong, readonly) MASConstraint *right; @property (nonatomic, strong, readonly) MASConstraint *bottom; @property (nonatomic, strong, readonly) MASConstraint *leading; @property (nonatomic, strong, readonly) MASConstraint *trailing; @property (nonatomic, strong, readonly) MASConstraint *width; @property (nonatomic, strong, readonly) MASConstraint *height; @property (nonatomic, strong, readonly) MASConstraint *centerX; @property (nonatomic, strong, readonly) MASConstraint *centerY; @property (nonatomic, strong, readonly) MASConstraint *baseline; //Margin Attribute @property (nonatomic, strong, readonly) MASConstraint *leftMargin; @property (nonatomic, strong, readonly) MASConstraint *rightMargin; @property (nonatomic, strong, readonly) MASConstraint *topMargin; @property (nonatomic, strong, readonly) MASConstraint *bottomMargin; @property (nonatomic, strong, readonly) MASConstraint *leadingMargin; @property (nonatomic, strong, readonly) MASConstraint *trailingMargin; @property (nonatomic, strong, readonly) MASConstraint *centerXWithinMargins; @property (nonatomic, strong, readonly) MASConstraint *centerYWithinMargins;

 

細看一下,MASConstraint中的Attribute和MASConstraintMaker徹底同樣。只是MASConstraintMaker中多了3種Convenient Attribute。ip

二者Attribute的一致,大大的提高了使用的方便性。使用過程當中咱們不用再去區分當前屬性是MASConstraint仍是MASConstraintMaker類型。(事實上沒研究他的類型以前,我都不知道他們分別屬於2種不一樣類的屬性)

 

UIView

 

咱們能夠看到在.equalTo(view1.superview.mas_left)裏面,superView也有Attribute。咱們來看看UIView中有哪些Attribute:

 

 

 
// Basic Attribute @property (nonatomic, strong, readonly) MASViewAttribute *mas_left; @property (nonatomic, strong, readonly) MASViewAttribute *mas_top; @property (nonatomic, strong, readonly) MASViewAttribute *mas_right; @property (nonatomic, strong, readonly) MASViewAttribute *mas_bottom; @property (nonatomic, strong, readonly) MASViewAttribute *mas_leading; @property (nonatomic, strong, readonly) MASViewAttribute *mas_trailing; @property (nonatomic, strong, readonly) MASViewAttribute *mas_width; @property (nonatomic, strong, readonly) MASViewAttribute *mas_height; @property (nonatomic, strong, readonly) MASViewAttribute *mas_centerX; @property (nonatomic, strong, readonly) MASViewAttribute *mas_centerY; @property (nonatomic, strong, readonly) MASViewAttribute *mas_baseline; // Margin Attribute @property (nonatomic, strong, readonly) MASViewAttribute *mas_leftMargin; @property (nonatomic, strong, readonly) MASViewAttribute *mas_rightMargin; @property (nonatomic, strong, readonly) MASViewAttribute *mas_topMargin; @property (nonatomic, strong, readonly) MASViewAttribute *mas_bottomMargin; @property (nonatomic, strong, readonly) MASViewAttribute *mas_leadingMargin; @property (nonatomic, strong, readonly) MASViewAttribute *mas_trailingMargin; @property (nonatomic, strong, readonly) MASViewAttribute *mas_centerXWithinMargins; @property (nonatomic, strong, readonly) MASViewAttribute *mas_centerYWithinMargins;

 

能夠看出,在UIView中的Attribute和MASConstraint中的幾乎如出一轍,只是每個Attribute加了一個mas_前綴。

因爲UIView是系統的類,對其擴展屬性和方法通常都須要添加本身的前綴,避免跟原有屬性和方法衝突。不過他們的意義跟MASConstraint中的Attribute是相同的

 

Relationship

 

 

約束表示的是2個item之間的關係,在Autolayout中一共定義了3種關係:=, >=, <=,對應到Masonry中:

- (MASConstraint * (^)(id attr))equalTo;
- (MASConstraint * (^)(id attr))greaterThanOrEqualTo;
- (MASConstraint * (^)(id attr))lessThanOrEqualTo;

相等關係咱們通常用的多。那麼不相等關係咱們何時用呢?

 

假如我有一個Label。Label的長度不能超出父View,若是label中的文字比較短,我但願是文字有多長,Label就有多長。
因爲label具備IntrinsicContentSize屬性。因此默認狀況下,他是文字有多長,Label就有多長。因此咱們只須要設置Label的長度小於父View便可

 

[label mas_makeConstraints:^(MASConstraintMaker *make) {    make.left.offset(0);    make.centerY.offset(0);    make.width.lessThanOrEqualTo(label.superview);}];

multiplier

multiplier表示Attribute前面的乘數。Masonry提供了2種添加multiplier的方法

//    Sets the NSLayoutConstraint multiplier property
- (MASConstraint * (^)(CGFloat multiplier))multipliedBy;

//    Sets the NSLayoutConstraint multiplier to 1.0/dividedBy
- (MASConstraint * (^)(CGFloat divider))dividedBy;

multipliedBy: 直接設置乘數
dividedBy: 設置乘數的倒數 multiplier = 1.0/dividedBy
通常寬或者高的約束使用multiplier比較多

 

Constant

 

Masonry提供了4種設置constant的方法

//Modifies the NSLayoutConstraint constant,only affects MASConstraints in which the first item's NSLayoutAttribute is one of the following NSLayoutAttributeTop, NSLayoutAttributeLeft, NSLayoutAttributeBottom, NSLayoutAttributeRight
- (MASConstraint * (^)(MASEdgeInsets insets))insets;

//Modifies the NSLayoutConstraint constant,only affects MASConstraints in which the first item's NSLayoutAttribute is one of the following NSLayoutAttributeWidth, NSLayoutAttributeHeight
- (MASConstraint * (^)(CGSize offset))sizeOffset;

//Modifies the NSLayoutConstraint constant, only affects MASConstraints in which the first item's NSLayoutAttribute is one of the following NSLayoutAttributeCenterX, NSLayoutAttributeCenterY
- (MASConstraint * (^)(CGPoint offset))centerOffset;

//Modifies the NSLayoutConstraint constant
- (MASConstraint * (^)(CGFloat offset))offset;

insets: 用來設置left, right, top, bottom。接受MASEdgeInsets類型值

sizeOffset: 用來設置width, height。接受CGSize類型的值
centerOffset: 用來設置centerX, centerY。接受CGPoint類型的值
offset: 能夠用來設置全部的東西。接受CGFloat類型的值

小技巧

  1. 若是等式2邊的Attribute是同樣的,咱們能夠省略等式右邊的Attribute
  2. 若是是等於關係,而且右邊的view是父View。連equalTo也能夠省略
  3. 若是equalTo裏面傳的是NSValue類型,效果跟設置offset是同樣的
  4. 若是offset爲0,其實也是能夠省略的...

下面全部代碼實際效果是同樣的:

// 完整的
make.left.equalTo(view1.superview.mas_left).offset(0);

//省略Attribute的
make.left.equalTo(view1.superview).offset(0);

//省略equalTo的
make.left.offset(0);

//使用equalTo替代offset的
make.left.equalTo(@0);

//終極大招,省略全部的... 惋惜會有warning
make.left;

對於這個警告咱們能夠將返回值轉爲空消除:

(void)make.left;

設置或更新約束

對於約束的設置,Masonry提供了3種方法,分別爲設置約束、更新約束、重寫設置約束

// 設置約束    
- (NSArray *)mas_makeConstraints:(void(^)(MASConstraintMaker *make))block;

// 更新約束
- (NSArray *)mas_updateConstraints:(void(^)(MASConstraintMaker *make))block;

// 從新設置約束
- (NSArray *)mas_remakeConstraints:(void(^)(MASConstraintMaker *make))block;

mas_makeConstraints: 初次設置約束使用。
mas_updateConstraints: 更新約束時使用。若是找不着這條約束,會新增,至關於mas_makeConstraints。
mas_remakeConstraints: 從新設置約束。先將view上全部約束移除,再新增約束

 

注意:mas_updateConstraints只能更新已有約束。若是第一次使用的是left, right設置的相對寬度。更新的時候想換成使用width。不能使用mas_updateConstraints,由於已有約束裏面沒有width的約束,新增width以後會跟原有left, right約束衝突。此時應該使用mas_remakeConstraints
 

批量設置約束

假設有View1,view2,view3三個View,咱們想要他們的寬高都等於CGSizeMake(100, 50)。咱們能夠對他們進行批量設置:

NSValue *sizeValue = [NSValue valueWithCGSize:CGSizeMake(100, 50)];
[@[view1,view2,view3] mas_makeConstraints:^(MASConstraintMaker *make) {
    make.size.equalTo(sizeValue);
}];

因爲咱們還要設置view的top,left等位置約束。那可不能夠在設置位置的mas_makeConstraints裏面批量設置寬高呢?實際是能夠的!

//advance set
[view1 mas_makeConstraints:^(MASConstraintMaker *make) {
    (void)make.top.left;
    make.size.equalTo(@[view2,view3,sizeValue]);
}];

不過須要注意的是。設置約束的時候,view必定是已經被addSubview的,不然會拋異常。因此咱們通常在最後一個view上加批量約束

Priority

咱們知道約束是有優先級的,Masonry給咱們提供了4個設置優先級的接口:

//    Sets the NSLayoutConstraint priority to a float or MASLayoutPriority
- (MASConstraint * (^)(MASLayoutPriority priority))priority;

//    Sets the NSLayoutConstraint priority to MASLayoutPriorityLow
- (MASConstraint * (^)())priorityLow;

//    Sets the NSLayoutConstraint priority to MASLayoutPriorityMedium
- (MASConstraint * (^)())priorityMedium;

//    Sets the NSLayoutConstraint priority to MASLayoutPriorityHigh
- (MASConstraint * (^)())priorityHigh;

priority: 能夠設置任意的優先級,接受的參數是0-1000的數字
priorityLow: 設置低優先級,優先級爲250
priorityMedium: 設置中優先級,優先級爲500
priorityHigh: 設置高優先級,優先級爲750

須要注意的是,使用priorityLow、priorityMedium、priorityHigh的時候。不是.priorityHigh,而是.priorityHigh()

 

Shorthand

在寫代碼的時候,可能你會感受有的東西要加mas_前綴,有的東西又不用加,代碼風格不統一,並且加mas_前綴還麻煩。

 

前面介紹過加mas_前綴主要是在擴展系統類的時候爲了不與原有類衝突,這是Apple推薦的作法。不過目前來講,即便不加mas_前綴,也不會有什麼問題。因此Masonry提供了不加mas_前綴的方法,只須要你定義幾個宏便可。

1, MAS_SHORTHAND
定義MAS_SHORTHAND宏以後。可使用UIView,NSArray中不帶mas_前綴的makeConstraints,updateConstraints,remakeConstraints。以及UIView中不帶mas_前綴的Attribute
2,  MAS_SHORTHAND_GLOBALS
默認的equalTo方法只接受id類型的對象。有時候咱們想傳入一個CGFloat, CGSize, UIEdgeInsets等。還須要將其轉化成NSValue對象,比較麻煩。Masonry也考慮到了這種狀況。只須要定義MAS_SHORTHAND_GLOBALS宏。就能夠直接對equalTo傳入基礎類型。Masonry自動轉化成NSValue對象

注意:#define MAS_SHORTHAND和#define MAS_SHORTHAND_GLOBALS這兩個宏要在導入Masonry以前定義

相關文章
相關標籤/搜索