原文链接
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
,为MASConstraint
的install
做准备;由
MASConstraintMaker
统一管理MASConstraint
的install
, 具体install
过程发生在MASConstraint
的- (void)install;
内;MASConstraint
中包含生成一个NSLayoutConstraint
所需要的所有信息;MASViewAttribute
是MASConstraint
的组成部分, 描述了生成一个NSLayoutConstraint
需要的 一组item
和NSLayoutAttribute
信息;
将 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;
}