源碼閱讀:Masonry(五)——MASCompositeConstraint

NO IMAGE

該文章閱讀的 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.總結

可以看到,該類只是簡單的保存傳入的約束對象數組,在調用方法時,遍歷數組調用約束對象各自的方法。

相關文章

源碼閱讀:Masonry(九)——NSArray+MASAdditions/其他分類

源碼閱讀:Masonry(八)——View+MASAdditions

源碼閱讀:Masonry(七)——MASConstraintMaker

源碼閱讀:Masonry(六)——MASViewConstraint