前提 :本文只是对Masonry做适当的实践,并不会介绍太多的概念,如果你还不知道什么是自动布局,什么是Masonry,它有什么优点,怎么引入项目,可以先了解了解,资料还是很多的。顺道提一下,自动布局和安卓的相对布局很类似。当你对这类布局有了一个比较完整的概念,当你拿到一个需求(界面UI效果图)的时候,在自己的思路里已经有了大体的框架和实现方式...
注意点
- 在使用Masonry添加约束之前,需要在addSubview之后才能使用,否则会导致崩溃。
- 约束出现问题的原因一般就是两种:约束冲突和缺少约束。对于这两种问题,可以通过调试和log排查。
基础使用
[root mas_makeConstraints:^(MASConstraintMaker *make) {
//添加约束
}];
[root mas_remakeConstraints:^(MASConstraintMaker *make) {
//移除之前的约束,重新添加新的约束
}];
[root mas_updateConstraints:^(MASConstraintMaker *make) {
//更新约束,原来的不变,更新哪个约束就是哪个约束
}];
(1) 添加约束
先添加一个简单的布局约束,然后看效果,代码和效果图如下
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
CGRect rectOfStatusbar = [[UIApplication sharedApplication] statusBarFrame];
UIView* root = [[UIView alloc] init];
self.view.backgroundColor =[UIColor whiteColor];
root.backgroundColor = [UIColor redColor];
[self.view addSubview:root];
[root mas_makeConstraints:^(MASConstraintMaker *make) {
//设置约束
make.top.equalTo(self.view).with.offset(rectOfStatusbar.size.height);
make.left.equalTo(self.view).with.offset(0.0f);
make.right.equalTo(self.view).with.offset(0.0f);
make.height.equalTo(@410);
}];
}
添加约束
(2) 设置布局的key方便我们定位错误
root.mas_key = @"红色布局";
下面我们给这个布局设置一个 -410高度的大小,可以看到控制台打印出来我们设置的key的错误日志。
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
CGRect rectOfStatusbar = [[UIApplication sharedApplication] statusBarFrame];
UIView* root = [[UIView alloc] init];
self.view.backgroundColor =[UIColor whiteColor];
root.backgroundColor = [UIColor redColor];
[self.view addSubview:root];
root.mas_key = @"红色布局";
[root mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.view).with.offset(rectOfStatusbar.size.height);
make.left.equalTo(self.view).with.offset(0.0f);
make.right.equalTo(self.view).with.offset(0.0f);
make.height.equalTo(@-410);
}];
}
错误信息
(3) 简单的思维分析
[root mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.view).with.offset(rectOfStatusbar.size.height);
make.left.equalTo(self.view).with.offset(0.0f);
make.right.equalTo(self.view).with.offset(0.0f);
make.height.equalTo(@410);
}];
我们先来看看MASConstraintMaker这个类
再看看我们的代码
make.left.equalTo(self.view).with.offset(0.0f);
这句代码,字面理解的意思就是:
left: 左边距
equalTo:等于谁的左边
with:看源码可以看到,其实我们可以省略掉,只是为了增加我们的代码可读性
- (MASConstraint *)with {
return self;
}
- (MASConstraint *)and {
return self;
}
offset:具体数值
我们连起来理解就是:相对某个布局添加一个左边距为多少(offset:具体数值)的约束。
如果这时候我们把我们的左边距由原来的 0 设置到10,我们看看效果
[root mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.view).with.offset(rectOfStatusbar.size.height);
//设置偏移量为 10 而且去掉了with(只是为了增强可读性无影响)
make.left.equalTo(self.view).offset(10.0f);
make.right.equalTo(self.view).with.offset(0.0f);
make.height.equalTo(@410);
}];
效果图
(4) 分析总结
由上面小点的简单分析情况,我们可以以此类推。
设置一个布局的
边距是:left、right、top、bottom
尺寸类:width、height
注意:right和bottom 设置的时候是取值为负,根据左边推算可以,右边往左边,是减少的,所以是设置为负数
题外话:安卓不会有这样的情况,哈哈哈
我们来设置一下右边距为20的布局看代码:
效果图
(4) equalTo 和 mas_equalTo
在上面的代码中,我们看到
//height 表示设置的高度约束
make.height.equalTo(@410);
当我们使用equalTo的时候我们设置了@410,如果设置410运行会报错,看MASConstraint这个类
#define mas_equalTo(...) equalTo(MASBoxValue((__VA_ARGS__)))
#define equalTo(...) mas_equalTo(__VA_ARGS__)
#define MASBoxValue(value) _MASBoxValue(@encode(__typeof__((value))), (value))
得出结论:mas_equalTo只是对其参数进行了一个装箱操作,参数可以传递基础数据类型对象,而equalTo这个方法不会对参数进行包装,只能传递对象类型,所以我们传410这个基本数据类型的时候,会报错。
(5) 中心对齐相关
center 中心对齐
centerY 横向中心对齐
centerX 纵向中心对齐
我们先添加一个正方形的红色UIView
红色View
设置 center 中心对齐
make.center.equalTo(self.view);
中心对齐
设置 centerY 纵向中心对齐
设置 centerX 横向中心对齐
横向中心对齐
以上演示总结:设置子布局相对于父布局的中心,可以让子布局分别对应父类的中心,纵向,横向中心对齐。
下面我们试试一个没有父子关系的布局是否可以设置中心对齐,
中心对齐 横向中心对齐 纵向中心对齐
结论:如果两个没有父子关系的布局设置对齐,设置约束的布局,会根据相对的布局的中心点来定位它自己的中心位置。
如果我们设置偏移量会有什么效果,看效果图
设置偏移的对齐
结论:如果设置了偏移量,设置偏移量的布局,会根据设置的数据,xy两个方向都会产生偏移。如果我们想设置单个方向的偏移,比如我们设置横向中心点对齐,然后横向向右便宜20。
单向偏移设置
纵向偏移的话,反过来设置就行。不再演示
(6)宽高的限制
// 设置宽度小于等于200
make.width.lessThanOrEqualTo(@200);
// 设置高度大于等于10
make.height.greaterThanOrEqualTo(@(10));
最后
以上练习了Masonry的一些基本使用,还有些知识的补充,留到下一节再继续演示。夜已深,先睡觉 ...