簡化iOS應用使用純代碼機型自適應布局的工作,使用一種簡潔高效的語法替代NSLayoutConstraints.
pod 'Masonry'推薦在你的在 PRefix.pch 中引入頭文件:
// 定義這個常量,就可以在使用Masonry不必總帶著前綴 `mas_`:#define MAS_SHORTHAND// 定義這個常量,以支持在 Masonry 語法中自動將基本類型轉換為 object 類型:#define MAS_SHORTHAND_GLOBALS#import "Masonry.h"這是使用MASConstraintMaker創建的約束:
/* 注意:view1應首先添加為某個視圖的子視圖,superview是一個局部變量,指view1的父視圖. */UIEdgeInsets padding = UIEdgeInsetsMake(10, 10, 10, 10);[view1 mas_makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(superview.mas_top).offset(padding.top); make.left.equalTo(superview.mas_left).offset(padding.left); make.bottom.equalTo(superview.mas_bottom).offset(-padding.bottom); make.right.equalTo(superview.mas_right).offset(-padding.right);}];甚至可以更短:
[view1 mas_makeConstraints:^(MASConstraintMaker *make) { make.edges.equalTo(superview).insets(padding);}];
.equalTo等價于 NSLayoutRelationEqual
.lessThanOrEqualTo等價于 NSLayoutRelationLessThanOrEqual
.greaterThanOrEqualTo等價于 NSLayoutRelationGreaterThanOrEqual
這三個表達相等關系的語句,可以接受一個參數;此參數可以為以下任意一個:
make.centerX.lessThanOrEqualTo(view2.mas_left);| MASViewAttribute | NSLayoutAttribute |
|---|---|
| view.mas_left | NSLayoutAttributeLeft |
| view.mas_right | NSLayoutAttributeRight |
| view.mas_top | NSLayoutAttributeTop |
| view.mas_bottom | NSLayoutAttributeBottom |
| view.mas_leading | NSLayoutAttributeLeading |
| view.mas_trailing | NSLayoutAttributeTrailing |
| view.mas_width | NSLayoutAttributeWidth |
| view.mas_height | NSLayoutAttributeHeight |
| view.mas_centerX | NSLayoutAttributeCenterX |
| view.mas_centerY | NSLayoutAttributeCenterY |
| view.mas_baseline | NSLayoutAttributeBaseline |
如果你需要 view.left 大于或等于label.left:
// 下面兩個約束是完全等效的.make.left.greaterThanOrEqualTo(label);make.left.greaterThanOrEqualTo(label.mas_left);自適應布局允許將寬度或高度設置為固定值.
如果你想要給視圖一個最小或最大值,你可以這樣:
//width >= 200 && width <= 400make.width.greaterThanOrEqualTo(@200);make.width.lessThanOrEqualTo(@400)但是自適應布局不支持將 left,right, centerY等設為固定值.
如果你給這些屬性傳遞一個常量, Masonry會自動將它們轉換為相對于其父視圖的相對值:
//creates view.left = view.superview.left + 10make.left.lessThanOrEqualTo(@10)除了使用 NSNumber 外,你可以使用基本數據類型或者結構體來創建約束:
make.top.mas_equalTo(42);make.height.mas_equalTo(20);make.size.mas_equalTo(CGSizeMake(50, 100));make.edges.mas_equalTo(UIEdgeInsetsMake(10, 0, 10, 0));make.left.mas_equalTo(view).mas_offset(UIEdgeInsetsMake(10, 0, 10, 0));一個數組,里面可以混合是前述三種類型的任意幾種:
// 表達三個視圖等高的約束.make.height.equalTo(@[view1.mas_height, view2.mas_height]);make.height.equalTo(@[view1, view2]);make.left.equalTo(@[view1, @100, view3.right]);
.priority允許你指定一個精確的優先級,數值越大優先級越高.最高1000.
.priorityHigh等價于 UILayoutPriorityDefaultHigh.優先級值為 750.
.priorityMedium介于高優先級和低優先級之間,優先級值在 250~750之間.
.priorityLow等價于 UILayoutPriorityDefaultLow, 優先級值為 250.
優先級可以在約束的尾部添加:
make.left.greaterThanOrEqualTo(label.mas_left).with.priorityLow();make.top.equalTo(label.mas_top).with.priority(600);
.multipliedBy允許你指定一個兩個視圖的某個屬性等比例變化
item1.attribute1 = multiplier × item2.attribute2 + constant,此為約束的計算公式,.multipliedBy本質上是用來限定multiplier的注意,因為編程中的坐標系從父視圖左上頂點開始,所以指定基于父視圖的left或者top的multiplier是沒有意義的,因為父視圖的left和top總為0.
如果你需要一個視圖隨著父視圖的寬度和高度,位置自動變化,你應該同時指定 right,bottom,width,height與父視圖對應屬性的比例(基于某個尺寸下的相對位置計算出的比例),并且constant必須為0.
// 指定寬度為父視圖的 1/4.make.width.equalTo(superview).multipliedBy(0.25);Masonry提供了一些工具方法來進一步簡化約束的創建.
//使 top, left, bottom, right等于 view2make.edges.equalTo(view2);//使 top = superview.top + 5, left = superview.left + 10,// bottom = superview.bottom - 15, right = superview.right - 20make.edges.equalTo(superview).insets(UIEdgeInsetsMake(5, 10, 15, 20))// 使寬度和高度大于或等于 titleLabelmake.size.greaterThanOrEqualTo(titleLabel)//使 width = superview.width + 100, height = superview.height - 50make.size.equalTo(superview).sizeOffset(CGSizeMake(100, -50))//使 centerX和 centerY = button1make.center.equalTo(button1)//使 centerX = superview.centerX - 5, centerY = superview.centerY + 10make.center.equalTo(superview).centerOffset(CGPointMake(-5, 10))你可以使用鏈式語法來增強代碼可讀性:
// 除top外,其他約束都與父視圖相等.make.left.right.bottom.equalTo(superview);make.top.equalTo(otherView);有時,你需要修改已經存在的約束來實現動畫效果或者移除/替換已有約束.
在 Masonry 中,有幾種不同的更新視圖約束的途徑:
你可以把 Masonry 語法返回的約束或約束數組,存儲到一個局部變量或者類的屬性中,以供后續操作某個約束.
// 聲明屬性@property (nonatomic, strong) MASConstraint *topConstraint;...// when making constraints[view1 mas_makeConstraints:^(MASConstraintMaker *make) { self.topConstraint = make.top.equalTo(superview.mas_top).with.offset(padding.top); make.left.equalTo(superview.mas_left).with.offset(padding.left);}];...// 然后你就可以操作這個屬性.[self.topConstraint uninstall];如果你只是想添加新的約束,你可以使用便利方法mas_updateConstraints,不需要使用 mas_makeConstraints. mas_updateConstraints,不會移除已經存在的約束(即使新舊約束間相互沖突).
// 重寫視圖的updateConstraints方法: 這是Apple推薦的添加/更新約束的位置.// 這個方法可以被多次調用以響應setNeedsUpdateConstraints方法.// setNeedsUpdateConstraints 可以被UIKit內部調用或者由開發者在自己的代碼中調用以更新視圖約束. - (void)updateConstraints { [self.growingButton mas_updateConstraints:^(MASConstraintMaker *make) { make.center.equalTo(self); make.width.equalTo(@(self.buttonSize.width)).priorityLow(); make.height.equalTo(@(self.buttonSize.height)).priorityLow(); make.width.lessThanOrEqualTo(self); make.height.lessThanOrEqualTo(self); }]; //根據apple機制,最后應調用父類的updateConstraints方法. [super updateConstraints];}mas_remakeConstraints與mas_updateConstraints相似,不同之處在于: mas_remakeConstraints 會先移除視圖上已有的約束,再去創建新的約束.
- (void)changeButtonPosition { [self.button mas_remakeConstraints:^(MASConstraintMaker *make) { make.size.equalTo(self.buttonSize); if (topLeft) { make.top.and.left.offset(10); } else { make.bottom.and.right.offset(-10); } }];}新聞熱點
疑難解答