源码阅读:Masonry(五)—— MASCompositeConstraint

332 阅读2分钟

该文章阅读的 Masonry 的版本为 1.1.0。

该类是 MASConstraint 类的一个子类,它封装着一组约束对象。这个对象应用于以下场景:

make.top.left.bottom.right.equalTo(self.view);

1.公共方法

- (id)initWithChildren:(NSArray *)children;

这个类的 .h 文件中,只有这一个方法,这个方法用于以指定的一组约束对象初始化该类对象。

2.类扩展

@property (nonatomic, strong) id mas_key;

这个属性保存用于标识约束的 key。


@property (nonatomic, strong) NSMutableArray *childConstraints;

这个属性保存着初始化时传入的约束对象数组。

3.实现

3.1 公共方法

- (id)initWithChildren:(NSArray *)children {
    self = [super init];
    if (!self) return nil;

    _childConstraints = [children mutableCopy];
    for (MASConstraint *constraint in _childConstraints) {
        constraint.delegate = self;
    }

    return self;
}

初始化方法中,除了保存传入的约束对象数组,还遍历数组设置了每个约束对象的代理。

3.2 MASConstraintDelegate 方法

- (void)constraint:(MASConstraint *)constraint shouldBeReplacedWithConstraint:(MASConstraint *)replacementConstraint {
    // 获取传入约束对象在数组中的位置,然后替换
    NSUInteger index = [self.childConstraints indexOfObject:constraint];
    NSAssert(index != NSNotFound, @"Could not find constraint %@", constraint);
    [self.childConstraints replaceObjectAtIndex:index withObject:replacementConstraint];
}
- (MASConstraint *)constraint:(MASConstraint __unused *)constraint addConstraintWithLayoutAttribute:(NSLayoutAttribute)layoutAttribute {
    // 获取当前对象的代理,也就是 MASConstraintMaker 对象
    id<MASConstraintDelegate> strongDelegate = self.delegate;
    // 调用 MASConstraintMaker 对象对该代理方法的实现获取到新约束对象
    MASConstraint *newConstraint = [strongDelegate constraint:self addConstraintWithLayoutAttribute:layoutAttribute];
    // 设置新约束对象的代理对象
    newConstraint.delegate = self;
    // 保存约束对象
    [self.childConstraints addObject:newConstraint];
    return newConstraint;
}

3.3 父类方法

- (MASConstraint * (^)(CGFloat))multipliedBy {
    return ^id(CGFloat multiplier) {
        for (MASConstraint *constraint in self.childConstraints) {
            constraint.multipliedBy(multiplier);
        }
        return self;
    };
}

- (MASConstraint * (^)(CGFloat))dividedBy {
    return ^id(CGFloat divider) {
        for (MASConstraint *constraint in self.childConstraints) {
            constraint.dividedBy(divider);
        }
        return self;
    };
}

- (MASConstraint * (^)(MASLayoutPriority))priority {
    return ^id(MASLayoutPriority priority) {
        for (MASConstraint *constraint in self.childConstraints) {
            constraint.priority(priority);
        }
        return self;
    };
}

- (MASConstraint * (^)(id, NSLayoutRelation))equalToWithRelation {
    return ^id(id attr, NSLayoutRelation relation) {
        for (MASConstraint *constraint in self.childConstraints.copy) {
            constraint.equalToWithRelation(attr, relation);
        }
        return self;
    };
}

- (MASConstraint *)animator {
    for (MASConstraint *constraint in self.childConstraints) {
        [constraint animator];
    }
    return self;
}

- (MASConstraint * (^)(id))key {
    return ^id(id key) {
        self.mas_key = key;
        int i = 0;
        for (MASConstraint *constraint in self.childConstraints) {
            constraint.key([NSString stringWithFormat:@"%@[%d]", key, i++]);
        }
        return self;
    };
}

- (void)setInsets:(MASEdgeInsets)insets {
    for (MASConstraint *constraint in self.childConstraints) {
        constraint.insets = insets;
    }
}

- (void)setInset:(CGFloat)inset {
    for (MASConstraint *constraint in self.childConstraints) {
        constraint.inset = inset;
    }
}

- (void)setOffset:(CGFloat)offset {
    for (MASConstraint *constraint in self.childConstraints) {
        constraint.offset = offset;
    }
}

- (void)setSizeOffset:(CGSize)sizeOffset {
    for (MASConstraint *constraint in self.childConstraints) {
        constraint.sizeOffset = sizeOffset;
    }
}

- (void)setCenterOffset:(CGPoint)centerOffset {
    for (MASConstraint *constraint in self.childConstraints) {
        constraint.centerOffset = centerOffset;
    }
}

- (void)activate {
    for (MASConstraint *constraint in self.childConstraints) {
        [constraint activate];
    }
}

- (void)deactivate {
    for (MASConstraint *constraint in self.childConstraints) {
        [constraint deactivate];
    }
}

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

- (void)uninstall {
    for (MASConstraint *constraint in self.childConstraints) {
        [constraint uninstall];
    }
}

可以看到这些方法的实现都是遍历出数组中的每一个约束对象,然后调用每个约束对象对应的方法,这类的约束对象其实就是 MASViewConstraint 类对象。

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

这个方法直接调用了该类对代理方法的实现。

4.总结

可以看到,该类只是简单的保存传入的约束对象数组,在调用方法时,遍历数组调用约束对象各自的方法。