基本原理
基于iOS系统的
Autolayout,是对系统autolayout的封装。根据
item1.attribute1 = multiplier * item2.attribute1 + offset构建一个NSLayoutConstraint将
NSLayoutConstraint添加到视图中。有些需要加入到视图自身上,有些需要加入到两个视图的最近父节点上面。找最近父节点,这其实是一个经典的算法题,可以有各种花哨的算法,而Masnory是通过双层循环,主要视图的层次结构不会嵌套很深,所以这样也不会太影响性能。
源码解析
- 通过
view category, 提供了设置布局的三个方法:- (NSArray *)mas_makeConstraints:(void(^)(MASConstraintMaker *make))block;- (NSArray *)mas_updateConstraints:(void(^)(MASConstraintMaker *make))block;- (NSArray *)mas_remakeConstraints:(void(^)(MASConstraintMaker *make))block;
以及@property (nonatomic, strong, readonly) MASViewAttribute *mas_left;等布局属性。
mas_makeConstraints实现:
- (NSArray *)mas_makeConstraints:(void(^)(MASConstraintMaker *))block {
self.translatesAutoresizingMaskIntoConstraints = NO;
MASConstraintMaker *constraintMaker = [[MASConstraintMaker alloc] initWithView:self];
block(constraintMaker);
return [constraintMaker install];
}
方法内部会先创建一个MASConstraintMaker的maker,并将此maker传入block执行,生成一堆layoutConstraints,最后在将layoutConstraints添加到对应的视图中。
mas_updateConstraints、mas_remakeConstraints与mas_makeConstraints类似,只是分别会设置maker的updateExisting、removeExisting属性。有啥用???
mas_left等布局属性:
- (MASViewAttribute *)mas_left {
return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeLeft];
}
生成一个对应MASViewAttribute 对象。MASViewAttribute这个类其实就是view和属性的一个包装而已。
-
MASConstraintMaker分析:
提供了@property (nonatomic, strong, readonly) MASConstraint *left;等单个layoutConstraint、@property (nonatomic, strong, readonly) MASConstraint *size;等复合布局约束、- (MASConstraint * (^)(dispatch_block_t))group;及上文中提及的install方法、updateExisting属性、removeExisting属性。
left属性
- (MASConstraint *)left {
return [self addConstraintWithLayoutAttribute:NSLayoutAttributeLeft];
}
调用
- (MASConstraint *)addConstraintWithLayoutAttribute:(NSLayoutAttribute)layoutAttribute {
return [self constraint:nil addConstraintWithLayoutAttribute:layoutAttribute];
}
size属性
- (MASConstraint *)addConstraintWithLayoutAttribute:(NSLayoutAttribute)layoutAttribute {
return [self constraint:nil addConstraintWithLayoutAttribute:layoutAttribute];
}