Masonry源码分析笔记
作者:互联网
Masonry是Objective-C中一款非常火爆的替代原生AutoLayout的第三方框架;相比原生而言,使用起来更简单、优雅。
其实,项目中很多地方都有用到,之前一直没有深入去探究其中的原理,最近得空,来做个简单的分析:
注意:分析之前请先查看MASUtilities.h,这里面重新定义了系统的一些类名(或者叫起别名),以方便理解。
使用方法
//先添加到父视图
[self.view addSubview:_statusLable];
//添加约束
__weak typeof(self) weakSelf = self;
[self.statusLable mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.mas_equalTo(10);
make.right.mas_equalTo(-10);
make.height.mas_equalTo(21);
make.top.equalTo(weakSelf.tipImage.mas_bottom).with.offset(10);
}];
其中,离我们最接近的就是这个mas_makeConstraints方法了,我们也由此入口来深入展开。
很明显,这个方法的参数是个block,没有返回值,携带一个MASConstraintMaker *类型的参数;然后我们就在这个block内部一通设置,就实现了相关布局,这也太神奇了吧~
其实,作者是把简单的用法留给了用户,复杂的功能自己实现了。
首先,通过分类(View+MASAdditions.h)的方式,给view添加了一系列的方法和属性(mas_left、mas_top等等)
//制作约束
- (NSArray *)mas_makeConstraints:(void(NS_NOESCAPE ^)(MASConstraintMaker *make))block;
//更新约束
- (NSArray *)mas_updateConstraints:(void(NS_NOESCAPE ^)(MASConstraintMaker *make))block;
//重做约束
- (NSArray *)mas_remakeConstraints:(void(NS_NOESCAPE ^)(MASConstraintMaker *make))block;
方法内部:
- (NSArray *)mas_makeConstraints:(void(^)(MASConstraintMaker *))block {
//确定是否将视图的自动调整遮罩转换为“自动布局”约束
self.translatesAutoresizingMaskIntoConstraints = NO;
//生成制作约束类的实例
MASConstraintMaker *constraintMaker = [[MASConstraintMaker alloc] initWithView:self];
//执行回调,暴露出去,用于设置相关约束
block(constraintMaker);
//安装所有约束并return
return [constraintMaker install];
}
首先,我们需要重点关注
block(constraintMaker);
所有我们之前设置的相关约束,都是通过这个函数传进来的。而这个MASConstraintMaker把约束都存了起来。
- (MASConstraint *)left {
return [self addConstraintWithLayoutAttribute:NSLayoutAttributeLeft];
}
- (MASConstraint *)top {
return [self addConstraintWithLayoutAttribute:NSLayoutAttributeTop];
}
- (MASConstraint *)right {
return [self addConstraintWithLayoutAttribute:NSLayoutAttributeRight];
}
- (MASConstraint *)bottom {
return [self addConstraintWithLayoutAttribute:NSLayoutAttributeBottom];
}
我们发现,使用过程中的.语法挺特别,作者在这里用到了链式调用,我们用以下使用方法来具体分析:
make.left.mas_equalTo(10);
make.left生成一个约束属性,并保存在make中,然后返回一个MASConstraint实例,供我们调用
- (MASConstraint *)left {
return [self addConstraintWithLayoutAttribute:NSLayoutAttributeLeft];
}
然后接着调用这个实例的equalTo方法
/**
返回block(返回值为MASConstraint类型,参数id类型)
*/
- (MASConstraint * (^)(id))equalTo {
return ^id(id attribute) {
return self.equalToWithRelation(attribute, NSLayoutRelationEqual);
};
}
上边代码猛地看起来有点儿晕,我们不妨慢慢分析、消化,这里建议倒着推:equalTo方法返回了一个block,那我们在调用方法时,其实就是间接调用了以下block
^id(id attribute) {
return self.equalToWithRelation(attribute, NSLayoutRelationEqual);
};
也就间接调用了equalToWithRelation函数,而我们传入的attribute,此时被equalToWithRelation函数执行,然后返回的MASConstraint实例方便我们继续设置。真是妙极了!block也被玩出了
标签:mas,return,secondViewAttribute,self,笔记,源码,Masonry,make,view 来源: https://blog.csdn.net/heartofthesea/article/details/89673527