Masonry源码解析

原文链接
Masonry 是一个基于 AutoLayout 的轻量级布局框架。

主要是对这两个API的封装:

- (void)addConstraint:(NSLayoutConstraint *)constraint;
- (void)removeConstraint:(NSLayoutConstraint *)constraint;
// NSLayoutConstraint 方法
+ (instancetype)constraintWithItem:(id)view1 attribute:(NSLayoutAttribute)attr1 relatedBy:(NSLayoutRelation)relation toItem:(nullable id)view2 attribute:(NSLayoutAttribute)attr2 multiplier:(CGFloat)multiplier constant:(CGFloat)c;

Masonry 每个类的职责划分

  • 核心类为 MASConstraintMaker ,负责收集 MASConstraint ,为 MASConstraintinstall 做准备;

  • MASConstraintMaker 统一管理 MASConstraintinstall, 具体 install 过程发生在 MASConstraint- (void)install; 内;

  • MASConstraint 中包含生成一个 NSLayoutConstraint 所需要的所有信息;

  • MASViewAttributeMASConstraint 的组成部分, 描述了生成一个 NSLayoutConstraint 需要的 一组 itemNSLayoutAttribute 信息;

NSLayoutConstraint 设置到 View 上

MASConstraint- (void)install; 部分代码如下,
针对 Masonry 的三个关键 API 不同的调用规则如下:

//  Masonry 的三个关键 API
- (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;
MASLayoutConstraint *existingConstraint = nil;
if (self.updateExisting) { //  mas_updateConstraints 调用时会走这里
    existingConstraint = [self layoutConstraintSimilarTo:layoutConstraint];
}
if (existingConstraint) { // mas_updateConstraints 调用,并且existingConstraint 不为 nil 时会走这里
    // just update the constant
    existingConstraint.constant = layoutConstraint.constant;
    self.layoutConstraint = existingConstraint;
} else { //  mas_makeConstraints 和 mas_remakeConstraints 调用。 或 mas_updateConstraints 调用 且existingConstraint 为 nil时走这里
    [self.installedView addConstraint:layoutConstraint];
    self.layoutConstraint = layoutConstraint;
    [firstLayoutItem.mas_installedConstraints addObject:self];
}

constraint的保存和移除

通过给UIView绑定一个set容器,存储加在当前view上的Contraints

- (NSMutableSet *)mas_installedConstraints {
    NSMutableSet *constraints = objc_getAssociatedObject(self, &kInstalledConstraintsKey);
    if (!constraints) {
        constraints = [NSMutableSet set];
        objc_setAssociatedObject(self, &kInstalledConstraintsKey, constraints, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    }
    return constraints;
}

你可能感兴趣的:(Masonry源码解析)