Auto Layout 與 Masonry
蘋果提供的自動布局(Auto Layout)能夠對視圖進行靈活有效的布局。但是,使用原生的自動布局相關的語法創建約束的過程是非常冗長的,可讀性也比較差。
Masonry 的目標其實就是?為了解決原生自動布局語法冗長的問題。
其實說到本質,它和手動布局是一樣的。對一個控件放在哪里,我們依然只關心它的(x, y, width, height)
。但手動布局的方式是,一次性計算出這四個值,然后設置進去,完成布局。但當父控件或屏幕發生變化時,子控件的計算就要重新來過,非常麻煩。
因此,在自動布局中,我們不再關心(x, y, width, height)
的具體值,我們只關心(x, y, width, height)
四個量對應的約束。
約束
添加約束的規則:
如果兩個控件是父子控件,則添加到父控件中。
如果兩個控件不是父子控件,則添加到層級最近的共同父控件中。
我們查看源碼:
基本屬性
添加約束的三種方法:
Masonry是基于AutoLayout實現計算視圖Frame的
// 定義這個常量,就可以不用在開發過程中使用"mas_"前綴。
#define MAS_SHORTHAND
// 定義這個常量,就可以讓Masonry幫我們自動把基礎數據類型的數據,自動裝箱為對象類型。
#define MAS_SHORTHAND_GLOBALS
Masonry的使用:
mas_equalTo和equalTo的區別
用法 | 常見場景 | 例子 |
---|---|---|
equalTo(view) | 對齊某個 view 的同屬性 | make.left.equalTo(self.view) |
equalTo(view.mas_xxx) | 對齊某個 view 的特定屬性 | make.left.equalTo(otherView.mas_right) |
equalTo(@數值) | 固定數值(必須手動包對象) | make.width.equalTo(@100) |
mas_equalTo(數值) | 固定數值、結構體(推薦寫法) | make.width.mas_equalTo(100 |
[button mas_makeConstraints:^(MASConstraintMaker *make) {make.top.equalTo(self.view).offset(20)make.bottom.equalTo(self.view).offset(0);make.right.equalTo(self.view).offset(10);make.left.equalTo(self.view).offset(200);make.centerX.equalTo(self.view);//水平居中make.centerY.equalTo(self.view);//垂直居中make.width.height.mas_equalTo(60);make.edges.equalTo(self.view).insets(UIEdgeInsetsMake(20, 20, 20, 20));//四周都留20make.width.equalTo(self.view).multipliedBy(0.5); //寬度 = 父視圖的一半}];
下圖為使用Masonry實現的折疊cell demo。
- (void)viewDidLoad {[super viewDidLoad];self.foldTableView = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStylePlain];self.foldTableView.delegate = self;self.foldTableView.dataSource = self;[self.view addSubview:self.foldTableView];[self.foldTableView mas_makeConstraints:^(MASConstraintMaker *make) {make.left.equalTo(self.view).offset(200);make.top.equalTo(self.view).offset(300);make.width.mas_equalTo(100);make.height.mas_equalTo(30);}];self.array = [NSMutableArray arrayWithObjects:@"1", @"2", @"3", @"4", @"5", nil];self.btn = [UIButton buttonWithType:UIButtonTypeCustom];[self.btn setImage:[UIImage imageNamed:@"kaiqi"] forState:UIControlStateNormal];[self.btn setImage:[UIImage imageNamed:@"guanbi"] forState:UIControlStateSelected];[self.btn addTarget:self action:@selector(press:) forControlEvents:UIControlEventTouchUpInside];[self.view addSubview:self.btn];[self.btn mas_makeConstraints:^(MASConstraintMaker *make) {make.left.equalTo(self.view).offset(270);make.top.equalTo(self.view).offset(300);make.width.mas_equalTo(40);make.height.mas_equalTo(40);}];
}