Masonry 开源库阅读心得
Masonry 是Facebook 开放的一个针对IOS 框架代码进行autolayout布局的开源库。
ios的自动布局(auotlayout)一般有两种方式:1.通过XIB或stroryBoard 实现,2.通过纯代码实现。
在实际项目中自动布局(autolayout)大部分情况是使用前者,但在前者不能实现或者很难实现情况下,采用了后者。如果使用ios系统自带的方式来实现autolayout,那将是一个很麻烦的事情。 而Masonry可以帮助我们轻松愉快地实现。
Masonry源码一般是从【UIView mas_makeConstraints:^(MASConstrraintMake *make) {
make.size.mas_equalTo(CGSizeMake(100,100));
make.top.mas_mas_equalTo(30);
}】开始的,mas_makeConstraints 内部就4行代码,
首先设置translatesAutoresizingMaskIntoConstraints 变量为NO,
第二行就创建一个MASConstraintMake对象,
第三行就调用block对象,其实就回到了make.size.mas_equalTo中,把用户自己加入的约束都添加上。
第四行执行【constrainMake install】,该函数内if (self.removeExisting) 的条件判断在调用mas_makeConstrains是不会执行的,该条件判断一般是调用mas_remakeConstrains接口才会执行。接着遍历约束数组,都执行[constraint install] 函数,该函数内重要的是如果已经存在该约束,就直接更新,否则就添加该约束到self.installedView数组中,
代码如下:
if (existingConstraint) {
// just update the constant
existingConstraint.constant = layoutConstraint.constant;
self.layoutConstraint = existingConstraint;
} else {
[self.installedView addConstraint:layoutConstraint];
self.layoutConstraint = layoutConstraint;
[firstLayoutItem.mas_installedConstraints addObject:self];
}
在遍历所有约束的时候,有个技术技巧:就是不直接操作self.constraints,而是重新拷贝一个新的约束数组(NSArray *constraints),这样保证了constraints数据的安全。
至于self.constraints数组是在何时装载数据的。答案就是在调用block的时候装载的,具体就是在mas_equalTo宏中。通过以上4行代码,就完成了约束的装载。
接下来看看mas_equalTo内部做的事情:
mas_equalTo 宏与equalTo函数的区别,前者支持CG等开头的对象,例如(CGSizeMake),后者只支持基本数据类型,例如int ,float之类的。 建议统一使用mas_equalTo宏。
mas_equalTo宏本质就是调用- (MASConstraint * (^)(id))equalTo函数,该函数就是调用self.equalToWithRelation函数,self.equalToWithRelation函数有两个参数,前一个参数attribute就是上层传入的参数,以上述例子为例就是mas_equalTo(CGSizeMake(100,100)) 或mas_equalTo(30);中的CGSizeMake(100,100) 或30,参数2设置为NSLayoutRelationEqual,结合mas_equalTo(30)例子就是等于30. 还可以设置大于30 或小于30.分别为NSLayoutRelationGreaterThanOrEqual和NSLayoutRelationLessThanOrEqual
self.equalToWithRelation函数内部就调用了- (MASConstraint * (^)(id, NSLayoutRelation))equalToWithRelation; 该函数主要是保存参数1和参数2, 不解的是就是仅仅做保存。没有操作。why??????
最后总结下:
1.Masonry开源库适合于纯代码方式的自动布局(autolayout),千万不要与Xib或stroyboard一起混用。原因是Masonry库只管理block内部添加的约束,对于Xib或stroyboard的系统约束没有管理。
2.关于自动布局的使用理解方式:若是屏幕居中,那就是left,top,right,bottom的offset各为一个数字,且size为(CGSizeMake(width,height)) ,当然也可以使用center设置;若是两个视图等宽,首先设置视图1的top,left,bottom边距以及size大小,接着设置视图2的top,bottom和right(视图1不能设置right, 视图2不能设置left)。第三步才设置视图1的right是相对视图2的left的。同理与两视图的等高。就要设置视图1的bottom相对于视图2的top了。 对于三视图就需要考虑视图1的right,视图2的left和right,视图3的left 三情况。
3.链式编程,Masonry库就是使用链式编程的(将多个方法用点语法链接起来),简单的理解就是view.top.left.right.bottom.mas_equalTo()中的.top.left之类的。对于这些方法就不用一个一个赋值了。