Masonry 作为常用的约束布局框架,我们需要对实现方式有自己的理解。通过查看源码发现 Masonry 是对 NSLayoutConstraint的二次封装,这里进行简单的源码分析。
目录
3、分析“ .left ”、“ .equalTo ” 等约束
一、简单实现
UIView * redView = [[UIView alloc]init];
redView.backgroundColor = [UIColor redColor];
[self.view addSubview:redView];
// 设置约束
[redView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.top.equalTo(@(100));
make.right.bottom.equalTo(@(-100));
}];
通过masonry创建一个距上下左右边距100的视图。
二、分析masonry源码
1、分析mas_makeConstraints
从 mas_makeConstraints 进入源码
- (NSArray *)mas_makeConstraints:(void(^)(MASConstraintMaker *))block {
self.translatesAutoresizingMaskIntoConstraints = NO;
MASConstraintMaker *constraintMaker = [[MASConstraintMaker alloc] initWithView:self];
block(constraintMaker);
return [constraintMaker install];
}
这里总共有四句代码:
1)清空之前的约束:
self.translatesAutoresizingMaskIntoConstraints = NO;
设置为NO即为将默认的自动约束关闭,防止约束冲突。
2)创建约束制造者MASConstraintMaker,initWithView会发现
- (id)initWithView:(MAS_VIEW *)view {
self = [super init];
if (!self) return nil;
self.view = view;
self.constraints = NSMutableArray.new;
return self;
}
绑定了需要约束的控件view,同时创建了一个用于装约束的空数组。
3)通过block对约束制造者constraintMaker进行约束添加,这里可以通过点击left约束进入源码,
if (!constraint) {
newConstraint.delegate = self;
[self.constraints addObject:newConstraint];
}
可以发现最终这个约束添加到了刚才创建的数组中。
4)最后安装约束,[constraintMaker install],此时约束已经添加完成。
2、分析 install
进入 install 源码
- (NSArray *)install {
if (self.removeExisting) {
NSArray *installedConstraints = [MASViewConstraint installedConstraintsForView:self.view];
for (MASConstraint *constraint in installedConstraints) {
[constraint uninstall];
}
}
NSArray *constraints = self.constraints.copy;
for (MASConstraint *constraint in constraints) {
constraint.updateExisting = self.updateExisting;
[constraint install];
}
[self.constraints removeAllObjects];
return constraints;
}
1)可以看到首先进行约束移除操作,然后遍历约束数组constraints对每个约束进行安装,然后进入单个约束的install。
2)在单个约束中首先取出两个相互约束的对象,如果第二个为空则取父视图,然后通过 MASLayoutConstraint 进行约束,这个 MASLayoutConstraint 是继承于 NSLayoutConstraint 的,从这里也可以看出 masonry 是基于 NSLayoutConstraint 的二次封装。
3)这里还有一些更新替换约束之类的操作,与创建约束类似。
3、分析“ .left ”、“ .equalTo ” 等约束
1)因为整体是通过链式编程完成的功能,所以进入源码可以看到不管是 MASConstraintMaker 还是 MASConstraint 都有对应的left,right。
2).left 是将约束直接添加到约束数组中,.equalTo 是将相互约束的控件保存到second里面,同时将约束数值保存起来,方便最后进行约束。
三、总结
masonry 是对 NSLayoutConstraint 的二次封装,通过链式编程让开发者使用起来更加方便,同时也是链式编程很好的例子,可以仔细研究下。