打开Masonry的源代码,能够发现两个属性php
/*ios
/**git
* Sets the NSLayoutConstraint multiplier propertygithub
*/框架
- (MASConstraint * (^)(CGFloat multiplier))multipliedBy;less
/**dom
* Sets the NSLayoutConstraint multiplier to 1.0/dividedByiphone
*/ide
- (MASConstraint * (^)(CGFloat divider))dividedBy;函数
*/
multipler属性表示约束值为约束对象的乘因数, dividedBy属性表示约束值为约束对象的除因数,可用于设置view的宽高比
这两个属性能够设置视图中的宽高比例
上代码。。
[aview makeConstraints:^(MASConstraintMaker *make) {
make.left.mas_equalTo(self.view);
make.bottom.mas_equalTo(self.view);
make.right.mas_equalTo(WeSelf.InputYuYinbtn.left);
make.height.mas_equalTo(aview.width).multipliedBy(0.6);// 高/宽 == 0.6
}];
自动布局最重要的是约束:UI元素间关系的数学表达式。约束包括尺寸、由优先级和阈值管理的相对位置。它们是添加剂,可能致使约束冲突 、约束不足形成布局没法肯定 。这两种状况都会产生异常。
setNeedsLayout
:告知页面须要更新,可是不会马上开始更新。执行后会马上调用layoutSubviews。layoutIfNeeded
:告知页面布局马上更新。因此通常都会和setNeedsLayout一块儿使用。若是但愿马上生成新的frame须要调用此方法,利用这点通常布局动画能够在更新布局后直接使用这个方法让动画生效。layoutSubviews
:系统重写布局setNeedsUpdateConstraints
:告知须要更新约束,可是不会马上开始updateConstraintsIfNeeded
:告知马上更新约束updateConstraints
:系统更新约束1. 基本使用
mas_makeConstraints
:添加约束mas_updateConstraints
:更新约束、亦可添加新约束mas_remakeConstraints
:重置以前的约束
multipler
属性表示约束值为约束对象的乘因数, dividedBy
属性表示约束值为约束对象的除因数,可用于设置view
的宽高比
// 进行屏幕的适配的时候,每每须要根据屏幕宽度来适配一个相应的高度,在此推荐使用以下约束的方式来进行控件的适配 [self.topView addSubview:self.topInnerView]; [self.topInnerView mas_makeConstraints:^(MASConstraintMaker *make) { make.height.equalTo(self.topView.mas_height).dividedBy(3); make.width.and.height.lessThanOrEqualTo(self.topView); make.width.and.height.equalTo(self.topView).with.priorityLow(); make.center.equalTo(self.topView); }];
priorityLow()
设置约束优先级#define MAS_SHORTHAND_GLOBALS
使用全局宏定义,可使equalTo
等效于mas_equalTo
#define MAS_SHORTHAND
使用全局宏定义, 能够在调用masonry方法的时候不使用mas_
前缀// 这里注意到一个地方,就是当使用了这个全局宏定义以后,发现能够有个类`NSArray+MASAdditions.h`,看了以后发现能够 self.buttonViews = @[ raiseButton, lowerButton, centerButton ]; // 以后能够在updateConstraints 方法中 - (void)updateConstraints { [self.buttonViews updateConstraints:^(MASConstraintMaker *make) { make.baseline.equalTo(self.mas_centerY).with.offset(self.offset); }]; [super updateConstraints]; }
// 建立视图约束 [blueView mas_makeConstraints:^(MASConstraintMaker *make) { self.animatableConstraint = make.edges.equalTo(superview).insets(paddingInsets).priorityLow(); ]]; // 更改约束 (另外一处方法中) UIEdgeInsets paddingInsets = UIEdgeInsetsMake(padding, padding, padding, padding); self.animatableConstraint.insets = paddingInsets; [self layoutIfNeeded];
debug
模式: // 对某个view添加key值 greenView.mas_key = @"greenView"; // 或者以下顺序 MASAttachKeys(greenView, redView, blueView, superview); // 一样的对每条约束亦能够添加key make.height.greaterThanOrEqualTo(@5000).key(@"ConstantConstraint");
preferredMaxLayoutWidth
: 多行label的约束问题// 已经确认好了位置 // 在layoutSubviews中确认label的preferredMaxLayoutWidth值 - (void)layoutSubviews { [super layoutSubviews]; // 你必须在 [super layoutSubviews] 调用以后,longLabel的frame有值以后设置preferredMaxLayoutWidth self.longLabel.preferredMaxLayoutWidth = self.frame.size.width-100; // 设置preferredLayoutWidth后,须要从新布局 [super layoutSubviews]; }
scrollView
使用约束的问题:原理经过一个contentView来约束scrollView的contentSize大小,也就是说以子控件的约束条件,来控制父视图的大小// 1. 控制scrollView大小(显示区域) [self.scrollView makeConstraints:^(MASConstraintMaker *make) { make.edges.equalTo(self.view); }]; // 2. 添加一个contentView到scrollView,而且添加好约束条件 [contentView makeConstraints:^(MASConstraintMaker *make) { make.edges.equalTo(self.scrollView); // 注意到此处的宽度约束条件,这个宽度的约束条件是比添加项 make.width.equalTo(self.scrollView); }]; // 3. 对contentView的子控件作好约束,达到能够控制contentView的大小
/** * 多个控件固定间隔的等间隔排列,变化的是控件的长度或者宽度值 * * @param axisType 轴线方向 * @param fixedSpacing 间隔大小 * @param leadSpacing 头部间隔 * @param tailSpacing 尾部间隔 */ - (void)mas_distributeViewsAlongAxis:(MASAxisType)axisType withFixedSpacing:(CGFloat)fixedSpacing l eadSpacing:(CGFloat)leadSpacing tailSpacing:(CGFloat)tailSpacing; /** * 多个固定大小的控件的等间隔排列,变化的是间隔的空隙 * * @param axisType 轴线方向 * @param fixedItemLength 每一个控件的固定长度或者宽度值 * @param leadSpacing 头部间隔 * @param tailSpacing 尾部间隔 */ - (void)mas_distributeViewsAlongAxis:(MASAxisType)axisType withFixedItemLength:(CGFloat)fixedItemLength leadSpacing:(CGFloat)leadSpacing tailSpacing:(CGFloat)tailSpacing;
使用方法很简单,由于它是NSArray的类扩展:
// 建立水平排列图标 arr中放置了2个或连个以上的初始化后的控件 // alongAxis 轴线方向 固定间隔 头部间隔 尾部间隔 [arr mas_distributeViewsAlongAxis:MASAxisTypeHorizontal withFixedSpacing:20 leadSpacing:5 tailSpacing:5]; [arr makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(@60); make.height.equalTo(@60); }];
2. 注意事项
addSubview
以后,才能给视图添加约束updateConstraints
内调用的时候,你就须要在此调用此方法,由于 updateConstraints
方法是须要触发的// 调用在view 内部,而不是viewcontroller + (BOOL)requiresConstraintBasedLayout { return YES; } /** * 苹果推荐 约束 增长和修改 放在此方法种 */ - (void)updateConstraints { [self.growingButton updateConstraints:^(MASConstraintMaker *make) { make.center.equalTo(self); make.width.equalTo(@(self.buttonSize.width)).priorityLow(); make.height.equalTo(@(self.buttonSize.height)).priorityLow(); make.width.lessThanOrEqualTo(self); make.height.lessThanOrEqualTo(self); }]; //最后记得回调super方法 [super updateConstraints]; }
// 通知须要更新约束,可是不当即执行 [self setNeedsUpdateConstraints]; // 当即更新约束,以执行动态变换 // update constraints now so we can animate the change [self updateConstraintsIfNeeded]; // 执行动画效果, 设置动画时间 [UIView animateWithDuration:0.4 animations:^{ [self layoutIfNeeded]; }];
1
|
MagicNumber -> autoresizingMask -> autolayout
|
以上是纯手写代码所经历的关于页面布局的三个时期
在iphone1-iphone3gs时代 window的size固定为(320,480) 咱们只须要简单计算一下相对位置就行了
在iphone4-iphone4s时代 苹果推出了retina屏 可是给了码农们很是大的福利:window的size不变
在iphone5-iphone5s时代 window的size变了(320,568) 这时autoresizingMask派上了用场(为啥这时候不用Autolayout? 由于还要支持ios5呗) 简单的适配一下便可
在iphone6+时代 window的width也发生了变化(相对5和5s的屏幕比例没有变化) 终因而时候抛弃autoresizingMask改用autolayout了(不用支持ios5了 相对于屏幕适配的多样性来讲autoresizingMask也已通过时了)
那如何快速的上手autolayout呢? 说实话 当年ios6推出的同时新增了autolayout的特性 我看了一下官方文档和demo 就立马抛弃到一边了 由于实在过于的繁琐和啰嗦(有过经验的朋友确定有同感)
直到iPhone6发布以后 我知道使用autolayout势在必行了 这时想起了之前在浏览Github看到过的一个第三方库Masonry 在花了几个小时的研究使用后 我就将autolayout掌握了(重点是我并无学习任何的官方文档或者其余的关于autolayout的知识) 这就是我为何要写下这篇文章来推荐它的缘由.
介绍
Masonry 源码:https://github.com/Masonry/Masonry
Masonry是一个轻量级的布局框架 拥有本身的描述语法 采用更优雅的链式语法封装自动布局 简洁明了 并具备高可读性 并且同时支持 iOS 和 Max OS X。
咱们先来看一段官方的sample code来认识一下Masonry
1
2
3
|
[view1 mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(superview).
with
.insets(padding);
}];
|
看到block里面的那句话: make edges equalTo superview with insets
经过链式的天然语言 就把view1给autolayout好了 是否是简单易懂?
使用
看一下Masonry支持哪一些属性
1
2
3
4
5
6
7
8
9
10
11
|
@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 *width;
@property (nonatomic, strong, readonly) MASConstraint *height;
@property (nonatomic, strong, readonly) MASConstraint *centerX;
@property (nonatomic, strong, readonly) MASConstraint *centerY;
@property (nonatomic, strong, readonly) MASConstraint *baseline;
|
这些属性与NSLayoutAttrubute的对照表以下
其中leading与left trailing与right 在正常状况下是等价的 可是当一些布局是从右至左时(好比阿拉伯文?没有相似的经验) 则会对调 换句话说就是基本能够不理不用 用left和right就行了
在ios8发布后 又新增了一堆奇奇怪怪的属性(有兴趣的朋友能够去瞅瞅) Masonry暂时还不支持(不过你要支持ios6,ios7 就不必去管那么多了)
在讲实例以前 先介绍一个MACRO
1
|
#define WS(weakSelf) __weak __typeof(&*self)weakSelf = self;
|
快速的定义一个weakSelf 固然是用于block里面啦 下面进入正题(为了方便 咱们测试的superView都是一个size为(300,300)的UIView)
下面 经过一些简单的实例来简单介绍如何轻松愉快的使用Masonry:
1. [基础] 居中显示一个view
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
- (void)viewDidLoad
{
[
super
viewDidLoad];
// Do any additional setup after loading the view.
WS(ws);
UIView *sv = [UIView
new
];
[sv showPlaceHolder];
sv.backgroundColor = [UIColor blackColor];
[self.view addSubview:sv];
[sv mas_makeConstraints:^(MASConstraintMaker *make) {
make.center.equalTo(ws.view);
make.size.mas_equalTo(CGSizeMake(300, 300));
}];
}
|
代码效果
使用我之间写的MMPlaceHolder 能够看到superview已经按照咱们预期居中而且设置成了适当的大小
那么先看看这几行代码
1
2
3
4
5
6
7
8
9
10
11
12
|
//今后之后基本能够抛弃CGRectMake了
UIView *sv = [UIView
new
];
//在作autoLayout以前 必定要先将view添加到superview上 不然会报错
[self.view addSubview:sv];
//mas_makeConstraints就是Masonry的autolayout添加函数 将所需的约束添加到block中行了
[sv mas_makeConstraints:^(MASConstraintMaker *make) {
//将sv居中(很容易理解吧?)
make.center.equalTo(ws.view);
//将size设置成(300,300)
make.size.mas_equalTo(CGSizeMake(300, 300));
}];
|
这里有两个问题要分解一下
首先在Masonry中可以添加autolayout约束有三个函数
1
2
3
4
5
6
7
8
9
|
- (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 则会清除以前的全部约束 仅保留最新的约束
三种函数善加利用 就能够应对各类状况了
*/
|
其次 equalTo 和 mas_equalTo的区别在哪里呢? 其实 mas_equalTo是一个MACRO
1
2
3
4
|
#define mas_equalTo(...) equalTo(MASBoxValue((__VA_ARGS__)))
#define mas_greaterThanOrEqualTo(...) greaterThanOrEqualTo(MASBoxValue((__VA_ARGS__)))
#define mas_lessThanOrEqualTo(...) lessThanOrEqualTo(MASBoxValue((__VA_ARGS__)))
#define mas_offset(...) valueOffset(MASBoxValue((__VA_ARGS__)))
|
能够看到 mas_equalTo只是对其参数进行了一个BOX操做(装箱) MASBoxValue的定义具体能够看看源代码 太长就不贴出来了
所支持的类型 除了NSNumber支持的那些数值类型以外 就只支持CGPoint CGSize UIEdgeInsets
介绍完这几个问题 咱们就继续往下了 PS:刚才定义的sv会成为咱们接下来全部sample的superView
2. [初级] 让一个view略小于其superView(边距为10)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
UIView *sv1 = [UIView
new
];
[sv1 showPlaceHolder];
sv1.backgroundColor = [UIColor redColor];
[sv addSubview:sv1];
[sv1 mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(sv).
with
.insets(UIEdgeInsetsMake(10, 10, 10, 10));
/* 等价于
make.top.equalTo(sv).with.offset(10);
make.left.equalTo(sv).with.offset(10);
make.bottom.equalTo(sv).with.offset(-10);
make.right.equalTo(sv).with.offset(-10);
*/
/* 也等价于
make.top.left.bottom.and.right.equalTo(sv).with.insets(UIEdgeInsetsMake(10, 10, 10, 10));
*/
}];
|
代码效果
能够看到 edges 其实就是top,left,bottom,right的一个简化 分开写也能够 一句话更省事
那么为何bottom和right里的offset是负数呢? 由于这里计算的是绝对的数值 计算的bottom须要小鱼sv的底部高度 因此要-10 同理用于right
这里有意思的地方是and和with 其实这两个函数什么事情都没作
1
2
3
4
5
6
|
- (MASConstraint *)
with
{
return
self;
}
- (MASConstraint *)and {
return
self;
}
|
可是用在这种链式语法中 就很是的巧妙和易懂 不得不佩服做者的心思(虽然我如今基本都会省略)
3. [初级] 让两个高度为150的view垂直居中且等宽且等间隔排列 间隔为10(自动计算其宽度)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
int padding1 = 10;
[sv2 mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerY.mas_equalTo(sv.mas_centerY);
make.left.equalTo(sv.mas_left).
with
.offset(padding1);
make.right.equalTo(sv3.mas_left).
with
.offset(-padding1);
make.height.mas_equalTo(@150);
make.width.equalTo(sv3);
}];
[sv3 mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerY.mas_equalTo(sv.mas_centerY);
make.left.equalTo(sv2.mas_right).
with
.offset(padding1);
make.right.equalTo(sv.mas_right).
with
.offset(-padding1);
make.height.mas_equalTo(@150);
make.width.equalTo(sv2);
}];
|
代码效果
这里咱们在两个子view之间互相设置的约束 能够看到他们的宽度在约束下自动的被计算出来了
4. [中级] 在UIScrollView顺序排列一些view并自动计算contentSize
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
|
UIScrollView *scrollView = [UIScrollView
new
];
scrollView.backgroundColor = [UIColor whiteColor];
[sv addSubview:scrollView];
[scrollView mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(sv).
with
.insets(UIEdgeInsetsMake(5,5,5,5));
}];
UIView *container = [UIView
new
];
[scrollView addSubview:container];
[container mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(scrollView);
make.width.equalTo(scrollView);
}];
int count = 10;
UIView *lastView = nil;
for
( int i = 1 ; i <= count ; ++i )
{
UIView *subv = [UIView
new
];
[container addSubview:subv];
subv.backgroundColor = [UIColor colorWithHue:( arc4random() % 256 / 256.0 )
saturation:( arc4random() % 128 / 256.0 ) + 0.5
brightness:( arc4random() % 128 / 256.0 ) + 0.5
alpha:1];
[subv mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.and.right.equalTo(container);
make.height.mas_equalTo(@(20*i));
if
( lastView )
{
make.top.mas_equalTo(lastView.mas_bottom);
}
else
{
make.top.mas_equalTo(container.mas_top);
}
}];
lastView = subv;
}
[container mas_makeConstraints:^(MASConstraintMaker *make) {
make.bottom.equalTo(lastView.mas_bottom);
}];
|
头部效果
尾部效果
从scrollView的scrollIndicator能够看出 scrollView的内部已如咱们所想排列好了
这里的关键就在于container这个view起到了一个中间层的做用 可以自动的计算uiscrollView的contentSize
5. [高级] 横向或者纵向等间隙的排列一组view
很遗憾 autoLayout并无直接提供等间隙排列的方法(Masonry的官方demo中也没有对应的案例) 可是参考案例3 咱们能够经过一个小技巧来实现这个目的 为此我写了一个Category
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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
|
@implementation UIView(Masonry_LJC)
- (void) distributeSpacingHorizontallyWith:(NSArray*)views
{
NSMutableArray *spaces = [NSMutableArray arrayWithCapacity:views.count+1];
for
( int i = 0 ; i < views.count+1 ; ++i )
{
UIView *v = [UIView
new
];
[spaces addObject:v];
[self addSubview:v];
[v mas_makeConstraints:^(MASConstraintMaker *make) {
make.width.equalTo(v.mas_height);
}];
}
UIView *v0 = spaces[0];
__weak __typeof(&*self)ws = self;
[v0 mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(ws.mas_left);
make.centerY.equalTo(((UIView*)views[0]).mas_centerY);
}];
UIView *lastSpace = v0;
for
( int i = 0 ; i < views.count; ++i )
{
UIView *obj = views[i];
UIView *space = spaces[i+1];
[obj mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(lastSpace.mas_right);
}];
[space mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(obj.mas_right);
make.centerY.equalTo(obj.mas_centerY);
make.width.equalTo(v0);
}];
lastSpace = space;
}
[lastSpace mas_makeConstraints:^(MASConstraintMaker *make) {
make.right.equalTo(ws.mas_right);
}];
}
- (void) distributeSpacingVerticallyWith:(NSArray*)views
{
NSMutableArray *spaces = [NSMutableArray arrayWithCapacity:views.count+1];
for
( int i = 0 ; i < views.count+1 ; ++i )
{
UIView *v = [UIView
new
];
[spaces addObject:v];
[self addSubview:v];
[v mas_makeConstraints:^(MASConstraintMaker *make) {
make.width.equalTo(v.mas_height);
}];
}
UIView *v0 = spaces[0];
__weak __typeof(&*self)ws = self;
[v0 mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(ws.mas_top);
make.centerX.equalTo(((UIView*)views[0]).mas_centerX);
}];
UIView *lastSpace = v0;
for
( int i = 0 ; i < views.count; ++i )
{
UIView *obj = views[i];
UIView *space = spaces[i+1];
[obj mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(lastSpace.mas_bottom);
}];
[space mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(obj.mas_bottom);
make.centerX.equalTo(obj.mas_centerX);
make.height.equalTo(v0);
}];
lastSpace = space;
}
[lastSpace mas_makeConstraints:^(MASConstraintMaker *make) {
make.bottom.equalTo(ws.mas_bottom);
}];
}
@end
|
简单的来测试一下
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
|
UIView *sv11 = [UIView
new
];
UIView *sv12 = [UIView
new
];
UIView *sv13 = [UIView
new
];
UIView *sv21 = [UIView
new
];
UIView *sv31 = [UIView
new
];
sv11.backgroundColor = [UIColor redColor];
sv12.backgroundColor = [UIColor redColor];
sv13.backgroundColor = [UIColor redColor];
sv21.backgroundColor = [UIColor redColor];
sv31.backgroundColor = [UIColor redColor];
[sv addSubview:sv11];
[sv addSubview:sv12];
[sv addSubview:sv13];
[sv addSubview:sv21];
[sv addSubview:sv31];
//给予不一样的大小 测试效果
[sv11 mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerY.equalTo(@[sv12,sv13]);
make.centerX.equalTo(@[sv21,sv31]);
make.size.mas_equalTo(CGSizeMake(40, 40));
}];
[sv12 mas_makeConstraints:^(MASConstraintMaker *make) {
make.size.mas_equalTo(CGSizeMake(70, 20));
}];
[sv13 mas_makeConstraints:^(MASConstraintMaker *make) {
make.size.mas_equalTo(CGSizeMake(50, 50));
}];
[sv21 mas_makeConstraints:^(MASConstraintMaker *make) {
make.size.mas_equalTo(CGSizeMake(50, 20));
}];
[sv31 mas_makeConstraints:^(MASConstraintMaker *make) {
make.size.mas_equalTo(CGSizeMake(40, 60));
}];
[sv distributeSpacingHorizontallyWith:@[sv11,sv12,sv13]];
[sv distributeSpacingVerticallyWith:@[sv11,sv21,sv31]];
[sv showPlaceHolderWithAllSubviews];
[sv hidePlaceHolder];
|
代码效果
perfect! 简洁明了的达到了咱们所要的效果
这里所用的技巧就是 使用空白的占位view来填充咱们目标view的旁边 这点经过图上的空白标注能够看出来
小结
经过以上5个案例 我以为已经把Masonry的经常使用功能介绍得差很少了 若是你以为意犹未尽呢 请下载官方的demo来学习
总而言之 Masonry是一个很是优秀的autolayout库 可以节省大量的开发和学习时间 尤为适合我这种纯代码的iOSer 在iPhone6发布后引起的适配潮中 Masonry必定能够助你一臂之力 :)
约束
,参照
frame
约束
,最终仍是为了肯定其位置
与尺寸
位置
,尺寸
这两个必要条件优先级
的约束优先级
会在例子中说明其用处
先添加四个View
UIView *redView = [[UIView alloc]init]; redView.backgroundColor = [UIColor redColor]; [self.view addSubview:redView]; UIView *blueView = [[UIView alloc]init]; blueView.backgroundColor = [UIColor blueColor]; [self.view addSubview:blueView]; UIView *yellow = [[UIView alloc]init]; yellow.backgroundColor = [UIColor yellowColor]; [self.view addSubview:yellow]; UIView *green = [[UIView alloc]init]; green.backgroundColor = [UIColor greenColor]; [self.view addSubview:green];
mas_makeConstraints
这个方法使左边等于self.view的左边,间距为0
and
与with
其实就是get调用者自己,里面仅仅是return self[redView mas_makeConstraints:^(MASConstraintMaker *make) { make.left.equalTo(self.view.mas_left).offset(0);//使左边等于self.view的左边,间距为0 make.top.equalTo(self.view.mas_top).offset(0);//使顶部与self.view的间距为0 make.width.equalTo(self.view.mas_width).multipliedBy(0.5);//设置宽度为self.view的一半,multipliedBy是倍数的意思,也就是,使宽度等于self.view宽度的0.5倍 make.height.equalTo(self.view.mas_height).multipliedBy(0.5);//设置高度为self.view高度的一半 }];
锚点
,来添加约束,肯定自身的位置
与尺寸
图1
中的blueView的效果,咱们应当怎样添加约束呢?[blueView mas_makeConstraints:^(MASConstraintMaker *make) { make.width.and.height.equalTo(redView);//使宽高等于redView make.top.equalTo(redView.mas_top);//与redView顶部对齐 make.leading.equalTo(redView.mas_right);//与redView的间距为0 }];
位置
与尺寸
[yellow mas_makeConstraints:^(MASConstraintMaker *make) { make.leading.equalTo(redView);//与redView左对齐 make.top.equalTo(redView.mas_bottom);//与redView底部间距为0 make.width.and.height.equalTo(redView);//与redView宽高相等 }]; [green mas_makeConstraints:^(MASConstraintMaker *make) { make.left.equalTo(yellow.mas_right);//与yellow右边间距为0 make.top.equalTo(blueView.mas_bottom);//与blueView底部间距为0 make.width.and.height.equalTo(redView);//与redView等宽高 }];
尺寸
的例子,或者是固定位置
的例子,我怕误导你们认为Autolayout是很是死板的,必须把每一个控件的约束添加到知足位置
与尺寸
,再去添加其余控件的约束,这样才不会出错位置
与尺寸
,可是有时这两个必须条件能够利用相对
来知足
相对
概念//代码中View的顺序与图中从左到右的View的顺序一致 //例子中,惟一不肯定的就是灰色View的宽度,咱们先把肯定的约束给一个一个的添加上来 //灰1左间距、高度、垂直位置(由于和红1底部对齐)是肯定的,添加约束 [gray1 mas_makeConstraints:^(MASConstraintMaker *make) { make.height.mas_equalTo(20); make.leading.equalTo(self.view.mas_leading).offset(0); make.bottom.equalTo(red1.mas_bottom); }]; //红1,宽高、左间距、底间距是肯定的,添加约束 [red1 mas_makeConstraints:^(MASConstraintMaker *make) { make.width.mas_equalTo(100); make.height.mas_equalTo(50); make.left.equalTo(gray1.mas_right); make.bottom.equalTo(self.view.mas_bottom).offset(-50); }]; //灰2,左间距、高度、垂直位置是肯定的,宽度要与灰1一致,是为了能均匀填充,添加约束 [gray2 mas_makeConstraints:^(MASConstraintMaker *make) { make.height.and.width.equalTo(gray1); make.leading.equalTo(red1.mas_right); make.bottom.equalTo(red1.mas_bottom); }]; //红2,宽高、左间距、底间距是肯定的,添加约束 [red2 mas_makeConstraints:^(MASConstraintMaker *make) { make.height.and.width.equalTo(red1); make.leading.equalTo(gray2.mas_right); make.bottom.equalTo(red1.mas_bottom); }]; //灰3,左间距、右间距、高度、垂直位置是肯定的,添加约束 [gray3 mas_makeConstraints:^(MASConstraintMaker *make) { make.height.and.width.equalTo(gray1); make.leading.equalTo(red2.mas_right); make.trailing.equalTo(self.view.mas_right); make.bottom.equalTo(red1.mas_bottom); }];
相对
,红色方块宽度是固定的,那么水平方向上的间距就须要剩下的三个灰色方块去填充,当界面横屏时,三个灰色方块为了相对
自身宽度要相同,相对
红色边界,self.view边界,间距保持为0,那么就得牺牲自身宽度的稳定,去维持这些相对
的约束UIView *redView = [[UIView alloc]init]; redView.backgroundColor = [UIColor redColor]; [self.view addSubview:redView]; UIView *greenView = [[UIView alloc]init]; greenView.backgroundColor = [UIColor greenColor]; [self.view addSubview:greenView]; UIView *blueView = [[UIView alloc]init]; blueView.backgroundColor = [UIColor blueColor]; [self.view addSubview:blueView]; [redView mas_makeConstraints:^(MASConstraintMaker *make) { make.left.equalTo(self.view.mas_left).offset(20); make.bottom.equalTo(self.view.mas_bottom).offset(-20); make.width.equalTo(self.view.mas_width).multipliedBy(0.2); make.height.equalTo(self.view.mas_height).multipliedBy(0.2); }]; [greenView mas_makeConstraints:^(MASConstraintMaker *make) { make.left.equalTo(redView.mas_right).offset(20); make.bottom.equalTo(self.view.mas_bottom).offset(-20); make.width.equalTo(self.view.mas_width).multipliedBy(0.2); make.height.equalTo(self.view.mas_height).multipliedBy(0.2); }]; [blueView mas_makeConstraints:^(MASConstraintMaker *make) { make.left.equalTo(greenView.mas_right).offset(20); make.bottom.equalTo(self.view.mas_bottom).offset(-20); make.width.equalTo(self.view.mas_width).multipliedBy(0.2); make.height.equalTo(self.view.mas_height).multipliedBy(0.2); make.left.equalTo(redView.mas_right).offset(20).priority(250); }];
[self.greenView removeFromSuperview]; [UIView animateWithDuration:1.0f animations:^{ [self.view layoutIfNeeded]; }];