Masonry是一个轻量级的布局框架,,对AutoLayout 进行了封装,它拥有自己的描述语法(采用更优雅的链式语法封装)来自动布局,具有很好可读性且同时支持iOS和Max OS X等。
第三方库地址:https://github.com/SnapKit/Masonry
Masonry的使用注意点
-
- 用mas_makeConstraints的那个view需要在addSubview之后才能用这个方法。
-
- mas_equalTo适用于数值元素,equalTo适用于属性。
-
- 方法and和with只是为了可读性,返回自身,可以省略。
-
- iOS中原点在左上角,所以注意使用offset时right和bottom用负数。
-
- Masonry 中的block是局部的引用,block内部引用self不会造成循环引用。
-
- 使用Masonry不需要设置控件的translatesAutoresizingMaskIntoConstraints属性为NO。
-
- 长度关系和位置关系,不能做比例运算
Masonry基础的设置属性与基础API
- 设置尺寸的属性:
@property (nonatomic, strong, readonly) MASConstraint *width;//宽度
@property (nonatomic, strong, readonly) MASConstraint *height;//高度
@property (nonatomic, strong, readonly) MASConstraint *size;//大小
- 设置边界的属性:
@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 *edges;//四周,即上下左右
- 设置中心点的属性:
@property (nonatomic, strong, readonly) MASConstraint *center;//中心点
@property (nonatomic, strong, readonly) MASConstraint *centerX;//中心点的X轴
@property (nonatomic, strong, readonly) MASConstraint *centerY;//中心点的Y轴
- 基础API:
//添加约束
- (NSArray *)mas_makeConstraints:(void(NS_NOESCAPE ^)(MASConstraintMaker *make))block;
//更新指定的约束,其他约束不变
- (NSArray *)mas_updateConstraints:(void(NS_NOESCAPE ^)(MASConstraintMaker *make))block;
//移除之前的约束,重新添加新的约束
- (NSArray *)mas_remakeConstraints:(void(NS_NOESCAPE ^)(MASConstraintMaker *make))block;
//相等于,参数是对象类型,一般是视图对象或视图坐标系对象
- (MASConstraint * (^)(id attr))equalTo;
//与equalTo相似,可以传递基础数据类型对象
- (MASConstraint * (^)(id attr))mas_equalTo;
//小于等于,参数是对象类型
- (MASConstraint * (^)(id attr))lessThanOrEqualTo;
//大于等于,参数是对象类型
- (MASConstraint * (^)(id attr))greaterThanOrEqualTo;
//乘以
- (MASConstraint * (^)(CGFloat multiplier))multipliedBy;
//除以
- (MASConstraint * (^)(CGFloat divider))dividedBy;
乘、除的使用。
-(void)setViewConstraints{
[self.redView mas_makeConstraints:^(MASConstraintMaker *make) {
make.center.equalTo(self.view);
make.size.mas_equalTo(CGSizeMake(100, 100));
}];
//例如除的运算是以redView 的centerX的位置除以2后,在x轴的原点右推redView的centerX的位置除以2后得到值
[self.greenView mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerY.equalTo(self.redView);
make.centerX.mas_equalTo(self.redView).dividedBy(2);
make.size.mas_equalTo(CGSizeMake(10, 10));
}];
}
得到的布局:
- 设置偏移量的函数:
- (void)setOffset:(CGFloat)offset;//设置偏移量,区分正负
- (void)setCenterOffset:(CGPoint)centerOffset;//设置中心点偏移量,区分正负
- (void)setSizeOffset:(CGSize)sizeOffset;//设置大小偏移量,区分正负
- (void)setInsets:(MASEdgeInsets)insets;//设置内边距偏移量,不区分正负
设置内边距时是不区分正负数的,因为Masonry为下、右方向为我们做了取反的操作。
-(void)setViewConstraints{
[self.redView mas_makeConstraints:^(MASConstraintMaker *make) {
make.center.equalTo(self.view);
make.size.mas_equalTo(CGSizeMake(100, 100));
}];
[self.greenView mas_makeConstraints:^(MASConstraintMaker *make) {
make.center.equalTo(self.redView);
make.edges.equalTo(self.redView).insets(UIEdgeInsetsMake(20,20,20,20));
}];
}
得到的布局:
- 设置约束优先级的函数:
//允许你指定一个精确的优先级,数值越大优先级越高.最高1000
- (MASConstraint * (^)(MASLayoutPriority priority))priority;
//等价于 UILayoutPriorityDefaultLow, 优先级值为 250.
- (MASConstraint * (^)(void))priorityLow;
//介于高优先级和低优先级之间,优先级值在 250~750之间.
- (MASConstraint * (^)(void))priorityMedium;
//等价于 UILayoutPriorityDefaultHigh.优先级值为 750
- (MASConstraint * (^)(void))priorityHigh;
在约束冲突的情况下,约束优先级低的约束将被打破。
-(void)setViewConstraints{
[self.redView mas_makeConstraints:^(MASConstraintMaker *make) {
make.center.equalTo(self.view);
make.size.mas_equalTo(CGSizeMake(100, 100));
}];
[self.greenView mas_makeConstraints:^(MASConstraintMaker *make) {
make.center.equalTo(self.redView).priorityLow();
make.size.mas_equalTo(CGSizeMake(50, 50));
make.left.equalTo(self.redView).offset(20).priorityHigh();
make.top.equalTo(self.redView).offset(5).priorityHigh();
}];
}
得到的布局是这样的:
当约束发生冲突时,可以使用Masonry提供的宏MASAttachKeys(...)来快速的定位冲突。
MASAttachKeys(self.redView,self.greenView);
未使用宏定位冲突时,控制台的打印:
"",
"",
"",
""
使用宏定位冲突时,控制台的打印:
"",
"",
"",
""
- 水平方向控件间隔固定等间隔,高度自定义,宽度由Masonry计算得出,垂直方向控件间隔固定等间隔,宽度自定义,高度由Masonry计算得出的布局。
/**
axisType 轴线方向
fixedSpacing 间隔大小
leadSpacing 头部间隔,水平布局即第一个控件与父视图的左间距,垂直布局,即第一个控件与父视图的上间距
tailSpacing 尾部间隔,水平布局即最后一个控件与父视图的右间距,垂直布局,即最后个控件与父视图的下间距
*/
- (void)mas_distributeViewsAlongAxis:(MASAxisType)axisType withFixedSpacing:(CGFloat)fixedSpacing leadSpacing:(CGFloat)leadSpacing tailSpacing:(CGFloat)tailSpacing;
水平等间隔
- (void)viewDidLoad {
[super viewDidLoad];
//创建3个视图
NSMutableArray *array= [[NSMutableArray alloc]init];
for(int i =0; i < 3; i ++) {
UIView *view = [UIView new];
if(i == 0){
view.backgroundColor = [UIColor redColor];
}else if(i == 1){
view.backgroundColor = [UIColor greenColor];
}else{
view.backgroundColor = [UIColor yellowColor];
}
[self.view addSubview:view];
[array addObject:view];
}
[array mas_distributeViewsAlongAxis:MASAxisTypeHorizontal withFixedSpacing:5 leadSpacing:5 tailSpacing:5];
[array mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerY.equalTo(self.view);
make.height.mas_equalTo(60);
}];
}
得到的布局:
- 水平方向控件宽度相等,高度自定义,控件间隔由Masonry计算,垂直方向控件高度相等,宽度自定义,控件间隔由Masonry计算得出的布局
/**
axisType 轴线方向
fixedSpacing 间隔大小
fixedItemLength 每个控件的固定长度/宽度
leadSpacing 头部间隔,水平布局即第一个控件与父视图的左间距,垂直布局,即第一个控件与父视图的上间距
tailSpacing 尾部间隔,水平布局即最后一个控件与父视图的右间距,垂直布局,即最后个控件与父视图的下间距
*/
- (void)mas_distributeViewsAlongAxis:(MASAxisType)axisType withFixedItemLength:(CGFloat)fixedItemLength leadSpacing:(CGFloat)leadSpacing tailSpacing:(CGFloat)tailSpacing;
垂直等间隔
- (void)viewDidLoad {
[super viewDidLoad];
//创建3个视图
NSMutableArray *array= [[NSMutableArray alloc]init];
for(int i =0; i < 3; i ++) {
UIView *view = [UIView new];
if(i == 0){
view.backgroundColor = [UIColor redColor];
}else if(i == 1){
view.backgroundColor = [UIColor greenColor];
}else{
view.backgroundColor = [UIColor yellowColor];
}
[self.view addSubview:view];
[array addObject:view];
}
[array mas_distributeViewsAlongAxis:MASAxisTypeVertical withFixedItemLength:70 leadSpacing:200 tailSpacing:200];
[array mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerX.equalTo(self.view);
make.width.mas_equalTo(70);
}];
}
得到的布局: