一、引子 學完了可視化編程的Xib和Storyboard,LZ對它們的感受就是的就是UI控制項創建直接拖拽,尺寸適配加約束,Storyboard的頁面跳轉邏輯清晰可見,比起代碼佈局節省了很多的工作量。但是LZ相信還是很多人喜歡用純代碼來編寫一個程式的(LZ就是一個,用代碼寫出來東西的成就感很足!),所 ...
一、引子
學完了可視化編程的Xib和Storyboard,LZ對它們的感受就是的就是UI控制項創建直接拖拽,尺寸適配加約束,Storyboard的頁面跳轉邏輯清晰可見,比起代碼佈局節省了很多的工作量。但是LZ相信還是很多人喜歡用純代碼來編寫一個程式的(LZ就是一個,用代碼寫出來東西的成就感很足!),所以今天在這裡給喜愛純代碼編程的程式猿們介紹一下純代碼約束佈局的工具——Masonry。
二、Masonry介紹
Masonry源碼下載地址:https://github.com/SoleMY/Masonry
Masonry是一個輕量級的佈局框架 擁有自己的描述語法 採用更優雅的鏈式語法封裝自動佈局 簡潔明瞭 並具有高可讀性 而且同時支持 iOS 和 Max OS X。
Masonry支持的屬性:
/// 左側 @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; // 在Masonry的源碼中我們可以看到他們對應的NSLayoutAttribute的屬性對應如下 - (MASConstraint *)left { return [self addConstraintWithLayoutAttribute:NSLayoutAttributeLeft]; } - (MASConstraint *)top { return [self addConstraintWithLayoutAttribute:NSLayoutAttributeTop]; } - (MASConstraint *)right { return [self addConstraintWithLayoutAttribute:NSLayoutAttributeRight]; } - (MASConstraint *)bottom { return [self addConstraintWithLayoutAttribute:NSLayoutAttributeBottom]; } - (MASConstraint *)leading { return [self addConstraintWithLayoutAttribute:NSLayoutAttributeLeading]; } - (MASConstraint *)trailing { return [self addConstraintWithLayoutAttribute:NSLayoutAttributeTrailing]; } - (MASConstraint *)width { return [self addConstraintWithLayoutAttribute:NSLayoutAttributeWidth]; } - (MASConstraint *)height { return [self addConstraintWithLayoutAttribute:NSLayoutAttributeHeight]; } - (MASConstraint *)centerX { return [self addConstraintWithLayoutAttribute:NSLayoutAttributeCenterX]; } - (MASConstraint *)centerY { return [self addConstraintWithLayoutAttribute:NSLayoutAttributeCenterY]; } - (MASConstraint *)baseline { return [self addConstraintWithLayoutAttribute:NSLayoutAttributeBaseline]; }
iOS8之後Masonry新出了幾個屬性:
/// 距離邊框的距離,等同於選中Storyboard的Constrain to margins後加約束 @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 *)leftMargin { return [self addConstraintWithLayoutAttribute:NSLayoutAttributeLeftMargin]; } - (MASConstraint *)rightMargin { return [self addConstraintWithLayoutAttribute:NSLayoutAttributeRightMargin]; } - (MASConstraint *)topMargin { return [self addConstraintWithLayoutAttribute:NSLayoutAttributeTopMargin]; } - (MASConstraint *)bottomMargin { return [self addConstraintWithLayoutAttribute:NSLayoutAttributeBottomMargin]; } - (MASConstraint *)leadingMargin { return [self addConstraintWithLayoutAttribute:NSLayoutAttributeLeadingMargin]; } - (MASConstraint *)trailingMargin { return [self addConstraintWithLayoutAttribute:NSLayoutAttributeTrailingMargin]; } - (MASConstraint *)centerXWithinMargins { return [self addConstraintWithLayoutAttribute:NSLayoutAttributeCenterXWithinMargins]; }
三、代碼示例
#import "RootViewController.h" // 引入頭文件 #import "Masonry.h" @interface RootViewController () @end @implementation RootViewController - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view. #pragma mark label // 添加約束,不需要設置frame UILabel *label = [UILabel new]; label.backgroundColor = [UIColor redColor]; // 添加父視圖,視圖添加完成後才能進行佈局 [self.view addSubview:label]; // 佈局實現label方法 [label mas_makeConstraints:^(MASConstraintMaker *make) { // 距離上邊50 // make:相當於你要佈局的視圖 // equalTo(參照視圖對象),如果參照視圖是self.view,可以不設置參照視圖的屬性 // offset(距離數值) make.top.equalTo(self.view).offset(50); // 距離左邊100 make.left.equalTo(self.view).offset(100); // 距離右邊100 make.right.equalTo(self.view).offset(-100); // 距離下邊500 make.bottom.equalTo(self.view).offset(-500); }]; #pragma mark label1 UILabel *label1 = [UILabel new]; label1.backgroundColor = [UIColor greenColor]; [self.view addSubview:label1]; // 佈局實現label1方法 // 先佈局參照視圖,否則約束容易丟失 [label1 mas_makeConstraints:^(MASConstraintMaker *make) { // equalTo(自定義視圖),需要設置視圖的屬性 // 如果數值為0,可以不寫offset() make.top.equalTo(label.mas_bottom).offset(50); make.leading.equalTo(label.mas_leading); make.trailing.equalTo(label.mas_trailing); // 高度60 // mas_equalTo(數值) make.height.mas_equalTo(60); }]; #pragma mark label2 UILabel *label2 = [UILabel new]; label2.backgroundColor = [UIColor grayColor]; [self.view addSubview:label2]; // 設置距離參照視圖的內邊距 (上左下右) UIEdgeInsets padding = UIEdgeInsetsMake(400, 100, 100, 100); // 佈局實現label2方法 // 先佈局參照視圖,否則約束容易丟失 [label2 mas_makeConstraints:^(MASConstraintMaker *make) { // 設置約束視圖的邊界距離self.view的邊界值 make.edges.equalTo(self.view).insets(padding); // make.top.equalTo(self.view).offset(400); // make.left.equalTo(self.view).offset(100); // make.right.equalTo(self.view).offset(-100); // // make.bottom.equalTo(self.view).offset(-100); }]; #pragma mark label3 UILabel *label3 = [UILabel new]; label3.backgroundColor = [UIColor orangeColor]; [self.view addSubview:label3]; [label3 mas_makeConstraints:^(MASConstraintMaker *make) { // 設置中心點一致 make.center.equalTo(label2); // 設置大小 // make.width = label2.width - 40 // make.heigth = label2.height - 60 make.size.equalTo(label2).sizeOffset(CGSizeMake(-40, -60)); }]; } @end
在這裡只是給大家舉幾個簡單的例子(效果圖):