一.Masonry简介

Masonry是一套轻量级的布局框架,它是对AutoLayout的封装,使用自己的一套框架来描述NSLayoutConstraints布局的DSL提高约束代码的简洁性和可读性。

Masonry采用链式编程使得代码清晰易懂,它同时支持iOS和Mac两个平台。

GitHub:https://github.com/SnapKit/Masonry

二.链式编程

在Obejective-C中,block形式上像一个函数,但同时又可以被当作一个变量。在Obejective-C中.操作符或者[object method]被编译器解释为objc_msgSend()方法调用,所以本质上.操作符和方括号语法是一样的。根据这种特性,我们可以利用block和.操作符来实现函数的链式写法。

  • 链式编程思想:把要做的事情封装到block,给外界提供一个返回这个block的方法。
  • 链式编程思想方法特点:方法返回值必须是block。block参数:传入需要操作的内容,block返回值:方法调用者。
UIView *demoView = [[UIView alloc] init];
demoView.backgroundColor = [UIColor blackColor];
[self.view addSubview:demoView];

[demoView mas_makeConstraints:^(MASConstraintMaker *make) {
    make.top.left.equalTo(self.view).offset(100);
    make.width.height.equalTo(@80);
}];

这是一个Masory的简单使用方法,可以看到mas_makeConstraints的处理内部使用make.width.height.equalTo(@80);这样的链式语句写法。

以下我们通过源码来简单看一下它里面的链式语法是如何实现的:

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

最上层调用mas_makeConstraints的时候它内部实现:

  • 创建一个约束制造者。
  • 调用block(constraintMaker),把所有的控件的约束全部保存到约束制造者。
  • [constraintMaker install],遍历约束制造者的所有约束给控件添加约束。

其中实现链式的关键步骤在于将所有约束保存到制造者这个过程上:

- (MASConstraint *)addConstraintWithLayoutAttribute:(NSLayoutAttribute)layoutAttribute {
    return [self constraint:nil addConstraintWithLayoutAttribute:layoutAttribute];
}

- (MASConstraint *)width {
    return [self addConstraintWithLayoutAttribute:NSLayoutAttributeWidth];
}

- (MASConstraint *)height {
    return [self addConstraintWithLayoutAttribute:NSLayoutAttributeHeight];
}

- (MASConstraint * (^)(id, NSLayoutRelation))equalToWithRelation;

- (MASConstraint * (^)(id))equalTo {
    return ^id(id attribute) {
        return self.equalToWithRelation(attribute, NSLayoutRelationEqual);
    };
}

首先make.width.height.equalTo(@80);的时候分别调用了width/height/equlTo这三个MASConstraint *内部的方法。而其中width/height方法是为这个对象添加上约束条件,而equlTo方法的返回是一个block所以最后调用(@80)来真正为这个对象内部的约束条件赋值。用OC的语义来表示就像[[[constraintMaker width] height] equalTo](@80)这么一个执行过程。

三.Masonry的使用

为了增加代码的可读性这里有两个简化代码的宏:

  • #define MAS_SHORTHAND和#define MAS_SHORTHAND_GLOBALS
  • MAS_SHORTHAND:只要在导入Masonry主头文件之前定义这个宏, 那么以后在使用Masonry框架中的属性和方法的时候, 就可以省略mas_前缀
  • MAS_SHORTHAND_GLOBALS:只要在导入Masonry主头文件之前定义这个宏,那么就可以让equalTo函数接收基本数据类型, 内部会对基本数据类型进行包装。

这两个宏如果想有效使用,必须要在添加Masonry头文件之前导入进去。

在Masonry中有三个基本方法:

  • mas_updateConstraints:更新约束条件,不删除已有的约束只重写要更新的那部分约束条件。
  • mas_remakeConstraints:重写约束条件,删除已有的约束再创建新的约束条件。
  • mas_makeConstraints:创建约束条件

在使用Masonry来创建约束之前必须要将这个视图添加到父视图上,不然会导致没有相对约束对象而崩溃。

results matching ""

    No results matching ""