Masonry是一个轻量级的布局框架 拥有自己的描述语法 采用更优雅的链式语法封装自动布局 简洁明了 并具有高可读性 而且同时支持 iOS 和 Max OS X。
Masonry是一个对系统NSLayoutConstraint进行封装的第三方自动布局框架,采用链式编程的方式提供给开发者API。系统AutoLayout支持的操作,Masonry都支持,相比系统API功能来说,Masonry是有过之而无不及。也就是说Masonry就是NSLayoutConstraint,只不过是提供了更加简单的书写方法。如果你对NSLayoutConstraint有所了解,那么Masonry可以说是简单易懂
Masonry属性与NSLayoutAttrubute的对照表如下
Masonry | NSLayoutAttrubute | 说明 |
---|---|---|
left | NSLayoutAttrubuteLeft | 左侧 |
top | NSLayoutAttrubuteTop | 上侧 |
right | NSLayoutAttrubuteRight | 右侧 |
bottom | NSLayoutAttrubuteBottom | 下侧 |
leading | NSLayoutAttrubuteLeading | 首部 |
trailing | NSLayoutAttrubuteTrailing | 尾部 |
width | NSLayoutAttrubuteWidth | 宽度 |
height | NSLayoutAttrubuteHeight | 高度 |
centerX | NSLayoutAttrubuteCenterX | 水平中心 |
centerY | NSLayoutAttrubuteCenterY | 竖直中心 |
baseline | NSLayoutAttrubuteBaseline | 文本基线 |
NSLayoutAttrubute
下面是用NSLayoutAttrubute,约束一个子视图,使之每个边与其父视图间距为10
UIView *superview = self.view;
UIView *view1 = [[UIView alloc] init];
view1.translatesAutoresizingMaskIntoConstraints = NO;
view1.backgroundColor = [UIColor greenColor];
[superview addSubview:view1];
UIEdgeInsets padding = UIEdgeInsetsMake(10, 10, 10, 10);
[superview addConstraints:@[
//view1 constraints
[NSLayoutConstraint constraintWithItem:view1
attribute:NSLayoutAttributeTop
relatedBy:NSLayoutRelationEqual
toItem:superview
attribute:NSLayoutAttributeTop
multiplier:1.0
constant:padding.top],
[NSLayoutConstraint constraintWithItem:view1
attribute:NSLayoutAttributeLeft
relatedBy:NSLayoutRelationEqual
toItem:superview
attribute:NSLayoutAttributeLeft
multiplier:1.0
constant:padding.left],
[NSLayoutConstraint constraintWithItem:view1
attribute:NSLayoutAttributeBottom
relatedBy:NSLayoutRelationEqual
toItem:superview
attribute:NSLayoutAttributeBottom
multiplier:1.0
constant:-padding.bottom],
[NSLayoutConstraint constraintWithItem:view1
attribute:NSLayoutAttributeRight
relatedBy:NSLayoutRelationEqual
toItem:superview
attribute:NSLayoutAttributeRight
multiplier:1
constant:-padding.right],
]];
而使用了Masonry实现相同的约束,仅仅需要几行代码
[view mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.insets(UIEdgeInsetsMake(10, 10, 10, 10));
}];
安装方式
Masonry支持CocoaPods,可以直接通过podfile文件进行集成,要在CocoaPods中添加下面代码:
pod 'Masonry'
pod install
之后直接在项目中引用即可,详情请参考github
使用方式
首先是约束的相关api
- (NSArray *)mas_makeConstraints:(void(^)(MASConstraintMaker *make))block;
- (NSArray *)mas_updateConstraints:(void(^)(MASConstraintMaker *make))block;
- (NSArray *)mas_remakeConstraints:(void(^)(MASConstraintMaker *make))block;
/*
mas_makeConstraints 只负责新增约束 Autolayout不能同时存在两条针对于同一对象的约束 否则会报错
mas_updateConstraints 针对上面的情况 会更新在block中出现的约束 不会导致出现两个相同约束的情况
mas_remakeConstraints 则会清除之前的所有约束 仅保留最新的约束
*/
在使用Masonry的约束之前,首先要将view添加到superview上
之后调用mas_makeConstraints添加相应的约束
居中
[view mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerX.equalTo(subView.mas_centerX); // 水平
make.centerY.equalTo(subView.mas_centerY); // 竖直
make.size.mas_equalTo(CGSizeMake(100, 100));
}];
水平居中 |
|
---|---|
竖直居中 |
|
居中 |
|
边距
// 添加一个与父视图上下左右都相距20的view
[view mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.insets(UIEdgeInsetsMake(20, 20, 20, 20));
/*
make.top.equalTo(subView).with.offset(20);
make.left.equalTo(subView).with.offset(20);
make.bottom.equalTo(subView).with.offset(-20);
make.right.equalTo(subView).with.offset(-20);
*/
}];
并列
// 两个子视图水平排列,之间的间距为20
[view1 mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerY.equalTo(subView.mas_centerY);
make.left.equalTo(subView.mas_left).with.offset(20);
make.right.equalTo(view2.mas_left).with.offset(-20);
make.height.mas_equalTo(@150);
make.width.equalTo(view2);
}];
[view2 mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerY.equalTo(subView.mas_centerY);
make.left.equalTo(view1.mas_right).with.offset(20);
make.right.equalTo(subView.mas_right).with.offset(-20);
make.height.mas_equalTo(@150);
make.width.equalTo(view1);
}];
// 两个子视图竖直并列,之间间距为20
[view1 mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerX.equalTo(subView.mas_centerX);
make.top.equalTo(subView.mas_top).with.offset(20);
make.bottom.equalTo(view2.mas_top).with.offset(-20);
make.width.mas_equalTo(@150);
make.height.equalTo(view2);
}];
[view2 mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerX.equalTo(subView.mas_centerX);
make.top.equalTo(view1.mas_bottom).with.offset(20);
make.bottom.equalTo(subView.mas_bottom).with.offset(-20);
make.width.mas_equalTo(@150);
make.height.equalTo(view1);
}];
// 上层左右并列,并与下层对其
[view1 mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerX.equalTo(subView.mas_centerX);
make.top.equalTo(subView.mas_top).with.offset(20);
make.bottom.equalTo(view2.mas_top).with.offset(-20);
make.left.equalTo(subView.mas_left).with.offset(20);
make.right.equalTo(view3.mas_left).with.offset(-20);
make.width.equalTo(view3.mas_width);
make.height.equalTo(view2);
}];
[view3 mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerX.equalTo(subView.mas_centerX);
make.top.equalTo(subView.mas_top).with.offset(20);
make.bottom.equalTo(view2.mas_top).with.offset(-20);
make.left.equalTo(view1.mas_right).with.offset(20);
make.right.equalTo(subView.mas_right).with.offset(-20);
make.width.mas_equalTo(view1.mas_width);
make.height.equalTo(view2);
}];
[view2 mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerX.equalTo(subView.mas_centerX);
make.top.equalTo(view1.mas_bottom).with.offset(20);
make.bottom.equalTo(subView.mas_bottom).with.offset(-20);
make.left.equalTo(subView.mas_right).with.offset(20);
make.right.equalTo(subView.mas_right).with.offset(-20);
make.height.equalTo(view1);
}];
// 右侧上下并列,并与左侧对其
[view1 mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerY.equalTo(subView.mas_centerY);
make.left.equalTo(subView.mas_left).with.offset(20);
make.right.equalTo(view2.mas_left).with.offset(-20);
make.top.equalTo(subView.mas_top).with.offset(20);
make.bottom.equalTo(subView.mas_bottom).with.offset(-20);
make.width.equalTo(view2);
}];
[view2 mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(view1.mas_right).with.offset(20);
make.right.equalTo(subView.mas_right).with.offset(-20);
make.top.equalTo(subView.mas_top).with.offset(20);
make.bottom.equalTo(view3.mas_top).with.offset(-20);
make.width.equalTo(view1);
make.height.equalTo(view3);
}];
[view3 mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(view1.mas_right).with.offset(20);
make.right.equalTo(subView.mas_right).with.offset(-20);
make.top.equalTo(view2.mas_bottom).with.offset(20);
make.bottom.equalTo(subView.mas_bottom).with.offset(-20);
make.width.equalTo(view1);
make.height.equalTo(view2);
}];
小结
以上仅仅是最最基础的布局,在实际的生产过程中要复杂许多。但是Masonry的确简化了NSLayoutConstraint的写法,使之更加语义化。虽然写法更加的复杂,对于团队开发也是一种规范。写下本笔记主要是为了记载自己学习Masonry的过程,暂时不能投入生产中,也无法更加熟练深刻的运用,仅记之以供后日查阅。