前提 :本文只是對Masonry做適當的實踐,並不會介紹太多的概念,如果你還不知道什麼是自動佈局,什麼是Masonry,它有什麼優點,怎麼引入專案,可以先了解了解,資料還是很多的。順道提一下,自動佈局和安卓的相對佈局很類似。當你對這類佈局有了一個比較完整的概念,當你拿到一個需求(介面UI效果圖)的時候,在自己的思路里已經有了大體的框架和實現方式...
Github地址 github.com/SnapKit/Mas…
注意點
- 在使用Masonry新增約束之前,需要在addSubview之後才能使用,否則會導致崩潰。
- 約束出現問題的原因一般就是兩種:約束衝突和缺少約束。對於這兩種問題,可以通過除錯和log排查。
基礎使用
[root mas_makeConstraints:^(MASConstraintMaker *make) {
//新增約束
}];
[root mas_remakeConstraints:^(MASConstraintMaker *make) {
//移除之前的約束,重新新增新的約束
}];
[root mas_updateConstraints:^(MASConstraintMaker *make) {
//更新約束,原來的不變,更新哪個約束就是哪個約束
}];
複製程式碼
(1) 新增約束
先新增一個簡單的佈局約束,然後看效果,程式碼和效果圖如下
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
CGRect rectOfStatusbar = [[UIApplication sharedApplication] statusBarFrame];
UIView* root = [[UIView alloc] init];
self.view.backgroundColor =[UIColor whiteColor];
root.backgroundColor = [UIColor redColor];
[self.view addSubview:root];
[root mas_makeConstraints:^(MASConstraintMaker *make) {
//設定約束
make.top.equalTo(self.view).with.offset(rectOfStatusbar.size.height);
make.left.equalTo(self.view).with.offset(0.0f);
make.right.equalTo(self.view).with.offset(0.0f);
make.height.equalTo(@410);
}];
}
複製程式碼

(2) 設定佈局的key方便我們定位錯誤
root.mas_key = @"紅色佈局";
複製程式碼
下面我們給這個佈局設定一個 -410高度的大小,可以看到控制檯列印出來我們設定的key的錯誤日誌。
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
CGRect rectOfStatusbar = [[UIApplication sharedApplication] statusBarFrame];
UIView* root = [[UIView alloc] init];
self.view.backgroundColor =[UIColor whiteColor];
root.backgroundColor = [UIColor redColor];
[self.view addSubview:root];
root.mas_key = @"紅色佈局";
[root mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.view).with.offset(rectOfStatusbar.size.height);
make.left.equalTo(self.view).with.offset(0.0f);
make.right.equalTo(self.view).with.offset(0.0f);
make.height.equalTo(@-410);
}];
}
複製程式碼

(3) 簡單的思維分析
[root mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.view).with.offset(rectOfStatusbar.size.height);
make.left.equalTo(self.view).with.offset(0.0f);
make.right.equalTo(self.view).with.offset(0.0f);
make.height.equalTo(@410);
}];
複製程式碼
我們先來看看MASConstraintMaker這個類

make.left.equalTo(self.view).with.offset(0.0f);
複製程式碼
這句程式碼,字面理解的意思就是: left: 左邊距 equalTo:等於誰的左邊 with:看原始碼可以看到,其實我們可以省略掉,只是為了增加我們的程式碼可讀性
- (MASConstraint *)with {
return self;
}
- (MASConstraint *)and {
return self;
}
複製程式碼
offset:具體數值
我們連起來理解就是:相對某個佈局新增一個左邊距為多少(offset:具體數值)的約束。
如果這時候我們把我們的左邊距由原來的 0 設定到10,我們看看效果
[root mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.view).with.offset(rectOfStatusbar.size.height);
//設定偏移量為 10 而且去掉了with(只是為了增強可讀性無影響)
make.left.equalTo(self.view).offset(10.0f);
make.right.equalTo(self.view).with.offset(0.0f);
make.height.equalTo(@410);
}];
複製程式碼

(4) 分析總結
由上面小點的簡單分析情況,我們可以以此類推。
設定一個佈局的
邊距是:left、right、top、bottom
尺寸類:width、height
注意:right和bottom 設定的時候是取值為負,根據左邊推算可以,右邊往左邊,是減少的,所以是設定為負數
題外話:安卓不會有這樣的情況,哈哈哈
複製程式碼
我們來設定一下右邊距為20的佈局看程式碼:

(4) equalTo 和 mas_equalTo
在上面的程式碼中,我們看到
//height 表示設定的高度約束
make.height.equalTo(@410);
複製程式碼
當我們使用equalTo的時候我們設定了@410,如果設定410執行會報錯,看MASConstraint這個類
#define mas_equalTo(...) equalTo(MASBoxValue((__VA_ARGS__)))
#define equalTo(...) mas_equalTo(__VA_ARGS__)
#define MASBoxValue(value) _MASBoxValue(@encode(__typeof__((value))), (value))
複製程式碼
得出結論:mas_equalTo只是對其引數進行了一個裝箱操作,引數可以傳遞基礎資料型別物件,而equalTo這個方法不會對引數進行包裝,只能傳遞物件型別,所以我們傳410這個基本資料型別的時候,會報錯。
(5) 中心對齊相關
center 中心對齊
centerY 橫向中心對齊
centerX 縱向中心對齊
複製程式碼
我們先新增一個正方形的紅色UIView

設定 center 中心對齊
make.center.equalTo(self.view);
複製程式碼

設定 centerY 縱向中心對齊


以上演示總結:設定子佈局相對於父佈局的中心,可以讓子佈局分別對應父類的中心,縱向,橫向中心對齊。
下面我們試試一個沒有父子關係的佈局是否可以設定中心對齊,



結論:如果兩個沒有父子關係的佈局設定對齊,設定約束的佈局,會根據相對的佈局的中心點來定位它自己的中心位置。
如果我們設定偏移量會有什麼效果,看效果圖


(6)寬高的限制
// 設定寬度小於等於200
make.width.lessThanOrEqualTo(@200);
// 設定高度大於等於10
make.height.greaterThanOrEqualTo(@(10));
複製程式碼
最後
以上練習了Masonry的一些基本使用,還有些知識的補充,留到下一節再繼續演示。夜已深,先睡覺 ...