Masonry源码分析一:MASConstraintMaker

MASConstraintMaker是Masonry框架运转的核心对象之一,我们知道,Masonry是基于AutoLayout技术的封装,所以我们来探寻一下MASConstraintMaker是如何发挥作用的。

先看一段典型的用法介绍:

[view1 mas_makeConstraints:^(MASConstraintMaker *make) {
    make.top.equalTo(superview.mas_top).with.offset(padding.top); //with is an optional semantic filler
    make.left.equalTo(superview.mas_left).with.offset(padding.left);
    make.bottom.equalTo(superview.mas_bottom).with.offset(-padding.bottom);
    make.right.equalTo(superview.mas_right).with.offset(-padding.right);
}];

第一部分 MASConstraintMaker与AutoLayout关系梳理

一、我们常用的 mas_makeConstraints方法的实现

- (NSArray *)mas_makeConstraints:(void(^)(MASConstraintMaker *))block {
    self.translatesAutoresizingMaskIntoConstraints = NO;
    MASConstraintMaker *constraintMaker = [[MASConstraintMaker alloc] initWithView:self];
    block(constraintMaker);
    return [constraintMaker install];
}

方法内部创建 MASConstraintMaker对象,然后传递到block中,执行完block,调用 [constraintMaker install]来确保约束被添加到视图中去。

二、上面MASConstraintMaker对象的[constraintMaker install]方法

for (MASConstraint *constraint in constraints) {
        constraint.updateExisting = self.updateExisting;
        [constraint install];
    }

可以看到,MASConstraintMaker包含很多的MASConstraint对象,然后逐一调用MASConstraint对象的install方法。

MASViewConstraint是MASConstraint的子类,创建NSLayoutConstraint添加到视图中去,看一下install方法:

...
MASLayoutConstraint *layoutConstraint
        = [MASLayoutConstraint constraintWithItem:firstLayoutItem
                                        attribute:firstLayoutAttribute
                                        relatedBy:self.layoutRelation
                                           toItem:secondLayoutItem
                                        attribute:secondLayoutAttribute
                                       multiplier:self.layoutMultiplier
                                         constant:self.layoutConstant];

...
...
...
[self.installedView addConstraint:layoutConstraint];

第二部分 查看MASConstraintMaker头文件

一、头文件第一部分

@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;

#if TARGET_OS_IPHONE

@property (nonatomic, strong, readonly) MASConstraint *leftMargin;
@property (nonatomic, strong, readonly) MASConstraint *rightMargin;
@property (nonatomic, strong, readonly) MASConstraint *topMargin;
@property (nonatomic, strong, readonly) MASConstraint *bottomMargin;
@property (nonatomic, strong, readonly) MASConstraint *leadingMargin;
@property (nonatomic, strong, readonly) MASConstraint *trailingMargin;
@property (nonatomic, strong, readonly) MASConstraint *centerXWithinMargins;
@property (nonatomic, strong, readonly) MASConstraint *centerYWithinMargins;

#endif

上面这些是比较常规的一些属性,在一开始的例子中

make.top.equalTo(superview.mas_top).with.offset(padding.top);

1、make.top  -->  返回一个MASConstraint对象</br>
2、top.equalTo  -->  返回一个block对象,equalTo对应的AutoLayout关系就是NSLayoutRelationEqual,block的接收参数是id类型,block返回值是MASConstraint类型</br>
3、equalTo(superview.mas_top)  -->  调用block,返回MASConstraint类型对象</br>
4、with可以忽略,offset类似,这里不详解MASConstraint对象

二、头文件第二部分

@property (nonatomic, strong, readonly) MASConstraint *(^attributes)(MASAttribute attrs);

@property (nonatomic, strong, readonly) MASConstraint *edges;

@property (nonatomic, strong, readonly) MASConstraint *size;

@property (nonatomic, strong, readonly) MASConstraint *center;

1、attributes  -->  返回一个block对象,block的接收参数是MASAttribute类型,返回MASCompositeConstraint对象</br>
2、edges  -->  返回一个MASConstraint对象,同时包含了上下左右的布局信息</br>
3、size  -->  返回一个MASConstraint对象,同时包含了宽高的布局信息</br>
4、center  -->  返回一个MASConstraint对象,同时包含了centerX和centerY信息

推荐阅读更多精彩内容