编程语言
首页 > 编程语言> > Masonry源码分析笔记

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