IOS基礎-Masonry 練習

JoezShare發表於2018-03-30

前提 :本文只是對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這個類

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

紅色View

設定 center 中心對齊

make.center.equalTo(self.view);
複製程式碼

中心對齊

設定 centerY 縱向中心對齊

縱向中心對齊
設定 centerX 橫向中心對齊
橫向中心對齊

以上演示總結:設定子佈局相對於父佈局的中心,可以讓子佈局分別對應父類的中心,縱向,橫向中心對齊。

下面我們試試一個沒有父子關係的佈局是否可以設定中心對齊,

中心對齊

橫向中心對齊

縱向中心對齊

結論:如果兩個沒有父子關係的佈局設定對齊,設定約束的佈局,會根據相對的佈局的中心點來定位它自己的中心位置。

如果我們設定偏移量會有什麼效果,看效果圖

設定偏移的對齊
結論:如果設定了偏移量,設定偏移量的佈局,會根據設定的資料,xy兩個方向都會產生偏移。如果我們想設定單個方向的偏移,比如我們設定橫向中心點對齊,然後橫向向右便宜20。
單向偏移設定
縱向偏移的話,反過來設定就行。不再演示

(6)寬高的限制

 // 設定寬度小於等於200
  make.width.lessThanOrEqualTo(@200);
  // 設定高度大於等於10
  make.height.greaterThanOrEqualTo(@(10));
複製程式碼

最後

以上練習了Masonry的一些基本使用,還有些知識的補充,留到下一節再繼續演示。夜已深,先睡覺 ...

相關文章