关于ios布局自动iphone6之后就是autolayout,autolayout固然非常好用,不过有时候我们需要在页面手动进行页面布局,vfl算是一种选择,而且vfl不复杂,理解起来很容易,实际开发中用的特别熟还好,要是第一次看估计要花点功夫才能搞定。masonry算是vfl的简化版,用的人比较多,之前项目中用过一次,对手动写页面的开发来说算是福利。
基础知识
首先我们看一个常见的问题将一个子view放在的uiviewcontroller的某个位置,通过设置边距来实现,效果如下:
如果通过vfl我们代码会是这样的:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
|
uiview *superview = self.view; uiview *view1 = [[uiview alloc] init]; view1.translatesautoresizingmaskintoconstraints = no; view1.backgroundcolor = [uicolor redcolor]; [superview addsubview:view1]; uiedgeinsets padding = uiedgeinsetsmake(200, 50, 200, 50); [superview addconstraints:@[ //约束 [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是如何实现的,导入masonry.h头文件,约束的代码:
1
2
3
4
5
6
7
8
9
|
uiview *childview=[uiview new ]; [childview setbackgroundcolor:[uicolor redcolor]]; //先将子view加入在父视图中 [self.view addsubview:childview]; __weak typeof(self) weakself = self; uiedgeinsets padding = uiedgeinsetsmake(200, 50, 200, 50); [childview mas_makeconstraints:^(masconstraintmaker *make) { make.edges.equalto(weakself.view).with.insets(padding); }]; |
通过mas_makeconstraints设置边距有种鸟枪换炮的感觉,我们即将开启一段新的旅程,可以紧接着看下面比较实用的功能~
实用知识
1.view设置大小
1
2
3
4
5
6
7
8
9
10
11
|
uiview *childview=[uiview new ]; [childview setbackgroundcolor:[uicolor redcolor]]; //先将子view加入在父视图中 [self.view addsubview:childview]; __weak typeof(self) weakself = self; [childview mas_makeconstraints:^(masconstraintmaker *make) { //设置大小 make.size.mas_equalto(cgsizemake(100, 100)); //居中 make.center.equalto(weakself.view); }]; |
效果如下:
这里友情其实一个小内容,目前我们设置约束都是通过mas_makeconstraints用来创建约束,mas_updateconstraints用来更新约束,mas_remakeconstraints重置约束,清除之前的约束,保留最新的约束,如果想深入解释下,可以阅读下面的英文解释~
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
/** * creates a masconstraintmaker with the callee view. * any constraints defined are added to the view or the appropriate superview once the block has finished executing * * @param block scope within which you can build up the constraints which you wish to apply to the view. * * @return array of created masconstraints */ - (nsarray *)mas_makeconstraints:( void (^)(masconstraintmaker *make))block; /** * creates a masconstraintmaker with the callee view. * any constraints defined are added to the view or the appropriate superview once the block has finished executing. * if an existing constraint exists then it will be updated instead. * * @param block scope within which you can build up the constraints which you wish to apply to the view. * * @return array of created/updated masconstraints */ - (nsarray *)mas_updateconstraints:( void (^)(masconstraintmaker *make))block; /** * creates a masconstraintmaker with the callee view. * any constraints defined are added to the view or the appropriate superview once the block has finished executing. * all constraints previously installed for the view will be removed. * * @param block scope within which you can build up the constraints which you wish to apply to the view. * * @return array of created/updated masconstraints */ - (nsarray *)mas_remakeconstraints:( void (^)(masconstraintmaker *make))block; |
2.设置高度,这里设置左右边距,因此不设置宽度,如果想单独设置width可参考高度的设置方式:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
uiview *childview=[uiview new ]; [childview setbackgroundcolor:[uicolor greencolor]]; //先将子view加入在父视图中 [self.view addsubview:childview]; __weak typeof(self) weakself = self; [childview mas_makeconstraints:^(masconstraintmaker *make) { //距离顶部44 make.top.equalto(weakself.view.mas_top).with.offset(44); //距离左边30 make.left.equalto(weakself.view.mas_left).with.offset(30); //距离右边30,注意是负数 make.right.equalto(weakself.view.mas_right).with.offset(-30); //高度150 make.height.mas_equalto(@150); }]; |
3.子视图之间的位置设置:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
uiview *childview=[uiview new ]; [childview setbackgroundcolor:[uicolor greencolor]]; //先将子view加入在父视图中 [self.view addsubview:childview]; __weak typeof(self) weakself = self; [childview mas_makeconstraints:^(masconstraintmaker *make) { //距离顶部44 make.top.equalto(weakself.view.mas_top).with.offset(44); //距离左边30 make.left.equalto(weakself.view.mas_left).with.offset(30); //距离右边30,注意是负数 make.right.equalto(weakself.view.mas_right).with.offset(-30); //高度150 make.height.mas_equalto(@150); }]; //地址:http://www.cnblogs.com/xiaofeixiang/ uiview *nextview=[uiview new ]; [nextview setbackgroundcolor:[uicolor redcolor]]; [self.view addsubview:nextview]; [nextview mas_makeconstraints:^(masconstraintmaker *make) { make.top.equalto(childview.mas_bottom).with.offset(30); make.right.equalto(childview.mas_right).with.offset(-30); make.width.mas_equalto(@100); make.height.mas_equalto(@100); }]; |
4.链式写法,算是一个便利的写法:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
uiview *childview=[uiview new ]; [childview setbackgroundcolor:[uicolor greencolor]]; //先将子view加入在父视图中 [self.view addsubview:childview]; __weak typeof(self) weakself = self; [childview mas_makeconstraints:^(masconstraintmaker *make) { make.top.and.left.mas_equalto(weakself.view).with.offset(100); make.bottom.and.right.mas_equalto(weakself.view).with.offset(-100); //第二种写法更简单,相对于就是父视图 // make.top.and.left.mas_equalto(100); // make.bottom.and.right.mas_equalto(-100); }]; uilabel *label=[uilabel new ]; [label settext:@ "博客园-flyelephant" ]; [label settextcolor:[uicolor redcolor]]; [label settextalignment:nstextalignmentcenter]; [self.view addsubview:label]; [label mas_makeconstraints:^(masconstraintmaker *make) { make.left.mas_equalto(weakself.view).with.offset(10); make.height.mas_equalto(20); make.right.mas_equalto(weakself.view).with.offset(-10); make.bottom.mas_equalto(weakself.view).with.offset(-50); }]; |
网上关于masonry的教程很多,给的例子的也很多,这几种情况基本上满足了开发中的需求,不会有太多的出入,算是一个简易版的教程,masonry的中属性和ios中的属性是有对应的关系,不过因为很简单,基本上没怎么看,下图是一个对照关系:
总结:
- 可以给控件添加left/right/top/bottom/size/height/width/insert约束;
- 库提供了三个方法,mas_makeconstraints添加约束,mas_updateconstraints修改约束,mas_remakeconstraints清除以前约束并添加新约束;
- 可以通过view.mas_bottom获得view的某个约束;
- 在约束的block中,使用make来给当前控件添加约束。