Masonry是iOS在控件布局中经常使用的一个轻量级框架,Masonry让NSLayoutConstraint使用起来更为简洁。Masonry简化了NSLayoutConstraint的使用方式,让我们可以以链式的方式为我们的控件指定约束。本篇博客的主题不是教你如何去使用Masonry框架的,而是对Masonry框架的源码进行解析,让你明白Masonry是如何对NSLayoutConstraint进行封装的,以及Masonry框架中的各个部分所扮演的角色是什么样的。在Masonry框架中,仔细的品味干货还是很多的。Masonry框架是Objective-C版本的,如果你的项目是Swift语言的,那么就得使用SnapKit布局框架了。SnapKit其实就是Masonry的Swift版本,两者虽然实现语言不同,但是实现思路大体一致。
今天博客对Masonry框架源码的解析思路是先对比给一个View添加同样的约束时,使用Masonry与系统原生的区别。然后就开门见山之间给出Masonry框架主要部分的类图,从类图中我们来整体的分析Masonry框架的结构。然后再由整体到部分逐渐的细化,窥探其内部的实现细节。通过上述步骤,我们将对Masonry框架的内部实现进行详细的了解。其实Masonry框架是轻量级的,总共的源码也没有多上行,但是仔细的阅读其实现细节,还是可以吸取很多实用的东西的。
首先Masonry在github上的地址是GitHub - SnapKit/Masonry: Harness the power of AutoLayout NSLayoutConstraints with a simplified, chainable and expressive syntax. Supports iOS and OSX Auto Layout, 你可以通过上述链接Clone到Masonry框架,其中有Masonry框架介绍以及一些Masonry的使用示例。关于Masonry的使用方式在今天的博客中就不做过多的赘述了,其具体的使用方式请参考上述github上的链接。今天我们就剖析一下Masonry框架的源码。
一、Masonry框架与NSLayoutConstraint调用方式的对比
首先我们NSLayoutConstraint为我们的View添加一个约束,然后再给出Masonry的代码。当然在此我们就不说Masonry添加约束的简洁行了,当然好东西是不需要宣传的。进入该部分的主题,我们要对一个View添加一个top约束,这个约束关系我们用表达式来表示就是“subView.top = superView.top + 10”。也就是子视图的top与父视图的top中间隔着10个pt。
1. 使用NSLayoutConstraint添加约束
下方这段代码就是给subView添加了一个相对于superView的Top约束。一个View要想确定位置一个约束是不够的,所以可想而知,我们要写多个下方的这样的约束来确定一个View的相对位置。其实下方就是一个表达式,NSLayoutConstraint构造器中每个参数构成这个表达式的一个组成部分。由上到下我们队参数个个参数进行解析,参数constraintWithItem用来指定所约束的对象,在此就是subView。第一个attribute参数则指定约束该对象的那个属性,在此就是subView的Top属性。参数relatedBy用来指定约束关系,比如大于等于,小于等于或者等于某个约束值。参数toItem则指定的是约束相对的对象,在此是相对superView的,所以此处的参数是superView。第二个attribute参数就是指定superView的Top属性。multiplier指定相对约束的倍数关系,constant则是约束的偏移量。
由上到下,NSLayoutConstraint的构造器中的参数会构成一个数学表达式,那就是subView.top = superView.top * 1 + 10,该表达式就直观的给出了subView.top与superView.top的关系。经下方的代码我们就为subView添加了一个相对于superView的Top约束,约束的偏移量是10。
2.使用Masonry添加上述约束
接下来就是Masonry出场的时刻了,我们将使用Masonry添加上述约束,其代码如下。下方给出了三种设置方式,下方三种方式是等价的,当然在Masonry中不知下方三种实现方式。下方Block中的每句话都代表着subView.top = superView.top * 1 + 10的意思,也就是说我们只需要写这三行代码中的其中一种即可。使用Masonry的好处一目了然,让你的代码更为简洁。
Masonry框架中支持约束的添加,约束的更新,约束的重建以及基本动画的实现等等。功能还是蛮强大的。在Masonry框架主要中采用了链式调用和匿名闭包的方式来简化约束的添加。有关Masonry更为详细的使用方式请参见上述Masonry框架的Github链接,具体使用方式在此就不做过多的赘述了。
二、Masonry框架的类结构
通过上述的Masonry的使用方式我们可以看出,UIView的对象可以直接调用mas_makeConstraints方法来为相应的View对象添加约束。因为mas_makeConstraints方法位于UIView的View+MASAdditions类目中,所以UIView的对象可以直接调用。同样在View+MASAdditions类目还有其他方法供UIView的对象使用,稍后会进行详细的介绍。
下方就是Masonry框架核心类以及类目之间