Masonry源代码解析

masonry源代码解析
摘要由CSDN通过智能技术生成

前言

简书地址:http://www.jianshu.com/p/cc945cc667b4
本文的中文注释代码demo更新在我的github上。

AutoLayout是Apple在iOS6中新增的UI布局适配的方法,用来替代iOS6之前的AutoResizeing。AutoLayout对应的代码约束就是NSLayoutConstraint。NSLayoutConstraint的API虽说时分简单,但约束的代码量较大,所以出现了很多对NSLayoutConstraint的封装,今天讲的就是其中最为有名的Masonry框架。

Masonry框架简化了约束NSLayoutConstraint的写法,在各种APP中都有很多的使用。Masonry是基于Objective-C语言的框架,Swift项目可以参考Snapkit框架。

本文会基于Masonry v1.0.1版本,同时借鉴了网上很多解析文章,对源代码进行解析,进行学习。


16.9.14更新:
MASViewConstraint的equalToWithRelation添加array缺少//viewConstraint.layoutRelation = relation;的pull request已经被接受,该问题fixed。

约束

NSLayoutConstraint约束是基于以下公式:

item1.attribute1 = multiplier × item2.attribute2 + constant

比如button1的左侧距离button2有10的约束会这么写:

button1.left = button2.right + 10;

事实上添加NSLayoutConstraint约束有三种方式:
* 1.storyboard/xib添加
* 2.VFL语言添加
* 3.NSLayoutConstraint纯代码添加

1.storyboard/xib添加

storyboard/xib添加NSLayoutConstraint的方式主要是右下角的约束设置:

xib右下角

分别是:
* Align
* Pin
* Resolve Auto Layout Issues

相应的图这里就不再贴了,有兴趣的可以自己去试一下

2.VFL语言添加

VFL(Visual Format Language)是苹果公司为了简化autolayout的编码而推出的抽象语言。
VFL调用以下方法:

+ (NSArray<__kindof NSLayoutConstraint *> *)constraintsWithVisualFormat:(NSString *)format 
options:(NSLayoutFormatOptions)opts 
metrics:(nullable NSDictionary<NSString *,id> *)metrics 
views:(NSDictionary<NSString *, id> *)views;

其中的format就是vfl语句。
vfl的语句也较为复杂,这里不详细介绍了,具体可以参考苹果文档Visual Format Language

3.NSLayoutConstraint纯代码添加

我们举一个例子:
view的上部距离距离superview有10的距离:

    NSLayoutConstraint *constraint = [NSLayoutConstraint constraintWithItem:view                        //view
                                                                  attribute:NSLayoutAttributeTop        //view.top
                                                                  relatedBy:NSLayoutRelationEqual       //view.top =
                                                                     toItem:superView                   //view.top = superView
                                                                  attribute:NSLayoutAttributeTop        //view.top = superView.top
                                                                 multiplier:1.0                         //view.top = 1.0 * superView.top
                                                                   constant:10.0];                      //view.top = 1.0 * superView.top + 10
    [view addConstraint:constraint];

可以看到约束代码算是列出了一个约束公式,也达到了约束的目的。
但这些代码,其实只写了一个top的约束,如果有其它约束代码,需要同样写类似的代码出来,所以直接用NSLayoutConstraint纯代码添加还是比较麻烦的一件事。

4.约束的限制

(1)对于两个同层级 view 之间的约束关系,添加到它们的父 view 上
(2)对于两个不同层级 view 之间的约束关系,添加到他们最近的共同父 view 上
(3)对于有层次关系的两个 view 之间的约束关系,添加到层次较高的父 view 上
(4)对于比如长宽之类的,只作用在该 view 自己身上的话,添加到该 view 自己上

Masonry的使用

1.Masonry的例子

Masonry的代码封装了NSLayoutConstraint纯代码,简洁了许多,和NSLayoutConstraint纯代码举同一个例子:
view的上部距离距离superview有10的距离

    [view mas_makeConstraints:^(MASConstraintMaker *make){
        make.top.equalTo(10);  //默认是父view 三者等价  view.top = 1.0 * superView.top + 10

        make.top.mas_equalTo(superView.mas_top).with.multipliedBy(1.0).mas_offset(10);

        make.top.equalTo(superView.top).offset(10);
    }];

相对于NSLayoutConstraint纯代码的添加约束,Masonry使用了block外加链式语法,使得调用简洁和方便了许多。

Masonry源代码

1.整体结构

Masonry的目录结构如下:

Masonry

文件比较多,借用iOS开发之Masonry框架源码深度解析的类图:

iOS开发之Masonry框架源码深度解析-Masonry类图

根据类图,文件目录主要分为以下几类:

  • 1.头文件和辅助文件
    Masonry.h:头文件
    MASUtilities.h:定义宏MASBoxValue,转换类型
    UIView+MASShorthandAdditions.h:定义UIView调用的简化参数和方法
    NSArray+MASShorthandAdditions.h:定义NSArray调用的简化参数和方法
    NSLayoutConstraint+MASDebugAdditions.h/m:DEBUG相关信息转换

  • 2.约束使用接口
    UIView+MASAdditions.h/m:UIView的约束接口
    UIViewController+MASAdditions.h/m:UIViewController的约束借口
    NSArray+MASAdditions.h/m:遍历NSArray中的UIView的约束接口

  • 3.约束建造者builder模式
    MASConstraintMaker.h/m:约束构造使用的建造者builder

  • 4.约束内部结构和实现
    MASLayoutConstraint.h/m:NSLayoutConstraint多了一层key的封装
    MASAttribute.h:NSLayoutAttribute的一层封装
    MASConstraint.h/m:定义链式结构体的抽象父类
    MASConstraint+Private.h:定义MASConstraint的接口和delegate代理
    MASViewConstraint.h/m:继承MASConstraint,表示view的约束结构体
    MASCompositeConstraint.h/m:继承MASConstraint,表示系列view组合的约束结构体

看了源代码会发现,Masonry的代码流程简单来讲就是:提供给用户一个建造者MASConstraintMaker,让用户根据mansory提供的语法,添加约束结构体MASConstraint。最后Masonry解析约束结构体MASConstraint,将真正的约束关系NSLayoutConstraint添加到相应的view上。

2.源代码探究

我们根据一个实际调用代码来讲Masonry的源代码。代码如下:

[view mas_makeConstraints:^(MASConstraintMaker *make){
        make.top.mas_equalTo(superView.mas_top).with.mas_offset(10);
}];

这边其实主要分两块
* MASConstraintMaker的链式调用
* view的约束函数调用

在讲这两块前,首先讲一下底层的数据结构MASConstraint相关的结构

(1)MASConstraint相关结构

MASConstraint是定义约束的抽象类(虽然OC没有抽象类的说法)
定义大概如下:

@interface MASConstraint : NSObject
...
- (MASConstraint * (^)(CGFloat offset))offset;
...
- (MASConstraint *)left;
- (MASConstraint *)top;
...
- (void)install;
- (void)uninstall;

这边只选取了部分方法和参数,来看一下相应的实现

- (MASC
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值