iOS界面布局之四——使用第三方庫Masonry進行autolayout布局
一、引言
在前面博客,我們討論了使用iOS原生的框架代碼來進行autolayout布局。在使用中,我們會發(fā)現(xiàn),無論是代碼量還是結(jié)構(gòu)的清晰度,都十分不能讓我們滿意,在storyBoard中只需要幾條線就可以搞定的事情,用代碼缺要寫冗余的一大堆。并且有些時候,故事版并不能解決所有問題,某些控件必須我們手寫,這樣的話,我們就不得不進行代碼的autolayout布局,幸運的是,Masonry可以幫助我們輕松愉快的完成這一任務(wù)。
使用代碼進行autolayout布局:http://my.oschina.net/u/2340880/blog 。
二、使用Masonry
這里說的大部分內(nèi)容均來自Masonry和官方gitHub,將其內(nèi)容進行了翻譯和解釋,源地址如下:https://github.com/SnapKit/Masonry。
1、布局的控件屬性對照
無論是用storyBoard還是代碼,在設(shè)置控件之間layout關(guān)系的時候,我們都需要設(shè)置控件的位置屬性。在下面的方法中,這個位置屬性就是NSLayoutAttribute對象,他決定的控件對象的參照位置:
1 2 3 4 5 | +(instancetype)constraintWithItem:(id)view1 attribute:(NSLayoutAttribute)attr1
relatedBy:(NSLayoutRelation)relation
toItem:(nullable id)view2
attribute:(NSLayoutAttribute)attr2
multiplier:(CGFloat)multiplier constant:(CGFloat)c;
|
在Masonry中,有一系列的屬性與之成對應(yīng)關(guān)系,對照如下:

2、3個方法讓你玩轉(zhuǎn)Masonry約束操作
Masonry在UIView的類別中,有3個全局的操作約束的方法,通過他們我們可以自由的進行autolayout的設(shè)置。
添加約束:
1 | - (NSArray *)mas_makeConstraints:(void(^)(MASConstraintMaker *make))block;
|
這個方法用于我們在最開始時為控件設(shè)置的約束,在block中進行約束條件的設(shè)置,例如我們創(chuàng)建一個label,將其尺寸設(shè)置為50*50,放在屏幕中間,使用如下代碼:
注意:在添加約束前,必須將視圖添加到其父視圖上。
1 2 3 4 5 6 7 8 9 10 11 12 | - (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
UILabel * label = [[UILabel alloc]init];
[self.view addSubview:label];
[label mas_makeConstraints:^(MASConstraintMaker *make) {
make.center.equalTo(self.view);
make.height.equalTo(@50);
make.width.equalTo(@50);
}];
label.backgroundColor = [UIColor redColor];
}
|
效果如下:

更新約束:
當(dāng)我們需要配合布局改變或者動畫效果的時候,我們可能需要將已經(jīng)添加的約束進行更新操作,使用如下的方法:
1 2 3 4 | [label mas_updateConstraints:^(MASConstraintMaker *make) {
make.height.equalTo(@100);
make.width.equalTo(@100);
}];
|
更新約束的作用在于更新已經(jīng)添加的某些約束,并不會移除掉原有的約束,如果我們需要添加新的約束,可以使用下面的重設(shè)約束的方法。
重設(shè)約束:
1 2 3 4 5 6 | [label mas_remakeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self.view.mas_left).offset(10);
make.top.equalTo(self.view.mas_top).offset(100);
make.height.equalTo(@100);
make.width.equalTo(@100);
}];
|
3、約束值相關(guān)
在添加具體約束的時候,我們不僅可以將約束值設(shè)置為絕對的相等關(guān)系,也可以設(shè)置一些值域的關(guān)系,在Masonry中,有如下三種:
1 2 3 4 5 6 | //絕對相等
- (MASConstraint * (^)(id attr))equalTo;
//大于等于
- (MASConstraint * (^)(id attr))greaterThanOrEqualTo;
//小于等于
- (MASConstraint * (^)(id attr))lessThanOrEqualTo;
|
對于約束的優(yōu)先級,使用如下幾個量:
1 2 3 4 5 6 7 8 | //手動設(shè)置一個優(yōu)先級參數(shù)
- (MASConstraint * (^)(MASLayoutPriority priority))priority;
//優(yōu)先級低
- (MASConstraint * (^)())priorityLow;
//優(yōu)先級中等
- (MASConstraint * (^)())priorityMedium;
//優(yōu)先級高
- (MASConstraint * (^)())priorityHigh;
|
寫法如下:
1 2 3 4 5 6 | [label mas_remakeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self.view.mas_left).offset(10);
make.top.equalTo(self.view.mas_top).offset(100);
make.height.equalTo(@100).priority(1000);
make.width.equalTo(@100).priorityHigh();
}];
|
三、Masonry設(shè)置約束的幾個示例
1、設(shè)置視圖與其父視圖的邊距約束
1 2 3 4 5 6 7 8 9 10 | - (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
label = [[UILabel alloc]init];
[self.view addSubview:label];
[label mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(self.view).insets(UIEdgeInsetsMake(20, 20, 20, 20));
}];
label.backgroundColor = [UIColor redColor];
}
|
設(shè)置上下左右與其父視圖邊距為20px,效果如下:
2、約束控件的尺寸為固定值
1 2 3 4 5 | [label mas_makeConstraints:^(MASConstraintMaker *make) {
make.height.equalTo(@200);
make.width.equalTo(@200);
make.center.equalTo(self.view);
}];
|
位置約束設(shè)置在了屏幕的中間,效果如下:

3、約束控件之間的尺寸
1 2 3 4 5 6 7 8 9 10 11 12 | [label mas_makeConstraints:^(MASConstraintMaker *make) {
make.height.equalTo(@100);
make.width.equalTo(label2);
make.right.equalTo(label2.mas_left).offset(-100);
make.leading.equalTo(self.view.mas_leading).offset(20);
make.centerY.equalTo(self.view);
}];
[label2 mas_makeConstraints:^(MASConstraintMaker *make) {
make.height.equalTo(@100);
make.centerY.equalTo(label);
make.trailing.equalTo(self.view.mas_trailing).offset(-20);
}];
|
設(shè)置了兩個label寬度一致,相距100px,分別距離左右邊距20px,效果如下:

|