本文共 9787 字,大约阅读时间需要 32 分钟。
在代码自动布局时,我们经常使用mansory来取代系统自带的autoLayout,mansory使用有如下注意点:
mas_makeConstraints 是给view添加约束,约束有几种,分别是边距,宽,高,左上右下距离,基准线。添加过约束后可以有修正,修正有offset(位移)修正和multipliedBy(倍率)修正。语法一般是 make.equalTo or make.greaterThanOrEqualTo or make.lessThanOrEqualTo + 倍数和位移修正。
注意点1: 使用 mas_makeConstraints方法的元素必须事先添加到父元素的中,例如[self.view addSubview:view],另外与该元素相关联的UI也必须事先添加到父元素中;
注意点2: masequalTo 和 equalTo 区别:masequalTo 比equalTo多了类型转换操作,一般来说,大多数时候两个方法都是 通用的,但是对于数值元素使用mas_equalTo。对于对象或是多个属性的处理,使用equalTo。特别是多个属性时,必须使用equalTo,例如 make.left.and.right.equalTo(self.view);
注意点3: 注意到方法with和and,这连个方法其实没有做任何操作,方法只是返回对象本身,这这个方法的左右完全是为了方法写的时候的可读性 。make.left.and.right.equalTo(self.view);和make.left.right.equalTo(self.view);是完全一样的,但是明显的加了and方法的语句可读性 更好点。
例1:`// Create viewsself.topView = [[UIView alloc] initWithFrame:CGRectZero]; self.topInnerView = [[UIView alloc] initWithFrame:CGRectZero]; self.bottomView = [[UIView alloc] initWithFrame:CGRectZero]; self.bottomInnerView = [[UIView alloc] initWithFrame:CGRectZero]; // Set background colors UIColor *blueColor = [UIColor colorWithRed:0.663 green:0.796 blue:0.996 alpha:1]; [self.topView setBackgroundColor:blueColor]; UIColor *lightGreenColor = [UIColor colorWithRed:0.784 green:0.992 blue:0.851 alpha:1]; [self.topInnerView setBackgroundColor:lightGreenColor]; UIColor *pinkColor = [UIColor colorWithRed:0.992 green:0.804 blue:0.941 alpha:1]; [self.bottomView setBackgroundColor:pinkColor]; UIColor *darkGreenColor = [UIColor colorWithRed:0.443 green:0.780 blue:0.337 alpha:1]; [self.bottomInnerView setBackgroundColor:darkGreenColor]; // Layout top and bottom views to each take up half of the window [self addSubview:self.topView]; [self.topView mas_makeConstraints:^(MASConstraintMaker *make) { make.left.right.and.top.equalTo(self); }]; [self addSubview:self.bottomView]; [self.bottomView mas_makeConstraints:^(MASConstraintMaker *make) { make.left.right.and.bottom.equalTo(self); make.top.equalTo(self.topView.mas_bottom); make.height.equalTo(self.topView); }]; // Inner views are configured for aspect fit with ratio of 3:1 [self.topView addSubview:self.topInnerView]; [self.topInnerView mas_makeConstraints:^(MASConstraintMaker *make) { make.width.equalTo(self.topInnerView.mas_height).multipliedBy(3); make.width.and.height.lessThanOrEqualTo(self.topView); make.width.and.height.equalTo(self.topView).with.priorityLow(); make.center.equalTo(self.topView); }]; [self.bottomView addSubview:self.bottomInnerView]; [self.bottomInnerView mas_makeConstraints:^(MASConstraintMaker *make) { make.height.equalTo(self.bottomInnerView.mas_width).multipliedBy(3); make.width.and.height.lessThanOrEqualTo(self.bottomView); make.width.and.height.equalTo(self.bottomView).with.priorityLow(); make.center.equalTo(self.bottomView); }];
运行效果如下:
这里写图片描述备注:multipliedBy()是倍数的意思,括号里面可以写任意数字;
lessThanOrEqualTo:小于或等于; greaterThanOrEqualTo:大于或等于; 优先级: 低级 - (MASConstraint * (^)())priorityLow { return ^id{ self.priority(MASLayoutPriorityDefaultLow); return self; }; } 中级 - (MASConstraint * (^)())priorityMedium { return ^id{ self.priority(MASLayoutPriorityDefaultMedium); return self; }; } 高级 - (MASConstraint * (^)())priorityHigh { return ^id{ self.priority(MASLayoutPriorityDefaultHigh); return self; }; }在Masonry中能够添加autolayout约束有三个函数
– (NSArray *)mas_makeConstraints:(void(^)(MASConstraintMaker *make))block; – (NSArray *)mas_updateConstraints:(void(^)(MASConstraintMaker *make))block; – (NSArray *)mas_remakeConstraints:(void(^)(MASConstraintMaker *make))block; /* mas_makeConstraints 只负责新增约束 Autolayout不能同时存在两条针对于同一对象的约束 否则会报错 mas_updateConstraints 针对上面的情况 会更新在block中出现的约束 不会导致出现两个相同约束的情况,更新约束的作用在于更新已经添加的某些约束,并不会移除掉原有的约束 mas_remakeConstraints 则会清除之前的所有约束 仅保留最新的约束 三种函数善加利用 就可以应对各种情况了 */ 其次 equalTo 和 mas_equalTo的区别在哪里呢? 其实 mas_equalTo是一个MACRO.#define mas_equalTo(…) equalTo(MASBoxValue((VA_ARGS)))
.#define mas_greaterThanOrEqualTo(…) greaterThanOrEqualTo(MASBoxValue((VA_ARGS))) .#define mas_lessThanOrEqualTo(…) lessThanOrEqualTo(MASBoxValue((VA_ARGS))) .#define mas_offset(…) valueOffset(MASBoxValue((VA_ARGS))) 可以看到 mas_equalTo只是对其参数进行了一个BOX操作(装箱) MASBoxValue的定义具体可以看看源代码 太长就不贴出来了所支持的类型 除了NSNumber支持的那些数值类型之外 就只支持CGPoint CGSize UIEdgeInsets
例2:UIView *sv1 = [UIView new];
[sv1 showPlaceHolder]; sv1.backgroundColor = [UIColor redColor]; [sv addSubview:sv1]; [sv1 mas_makeConstraints:^(MASConstraintMaker *make) { make.edges.equalTo(sv).with.insets(UIEdgeInsetsMake(10, 10, 10, 10));/* 等价于
make.top.equalTo(sv).with.offset(10); make.left.equalTo(sv).with.offset(10); make.bottom.equalTo(sv).with.offset(-10); make.right.equalTo(sv).with.offset(-10); *//* 也等价于
make.top.left.bottom.and.right.equalTo(sv).with.insets(UIEdgeInsetsMake(10, 10, 10, 10)); */ }];例3:在UIScrollView顺序排列一些view并自动计算contentSize
UIScrollView *scrollView = [UIScrollView new];scrollView.backgroundColor = [UIColor whiteColor];[sv addSubview:scrollView];[scrollView mas_makeConstraints:^(MASConstraintMaker *make) { make.edges.equalTo(sv).with.insets(UIEdgeInsetsMake(5,5,5,5));}];UIView *container = [UIView new];[scrollView addSubview:container];[container mas_makeConstraints:^(MASConstraintMaker *make) { make.edges.equalTo(scrollView); make.width.equalTo(scrollView);}];int count = 10;UIView *lastView = nil;for ( int i = 1 ; i <= count ; ++i ){ UIView *subv = [UIView new]; [container addSubview:subv]; subv.backgroundColor = [UIColor colorWithHue:( arc4random() % 256 / 256.0 ) saturation:( arc4random() % 128 / 256.0 ) + 0.5 brightness:( arc4random() % 128 / 256.0 ) + 0.5 alpha:1]; [subv mas_makeConstraints:^(MASConstraintMaker *make) { make.left.and.right.equalTo(container); make.height.mas_equalTo(@(20*i)); if ( lastView ) { make.top.mas_equalTo(lastView.mas_bottom); } else { make.top.mas_equalTo(container.mas_top); } }]; lastView = subv;}[container mas_makeConstraints:^(MASConstraintMaker *make) { make.bottom.equalTo(lastView.mas_bottom);}];
例4 横向或者纵向等间隙的排列一组view
我们可以通过一个Category来实现该目的
@implementation UIView(Masonry_LJC)
- (void) distributeSpacingHorizontallyWith:(NSArray*)views { NSMutableArray *spaces = [NSMutableArray arrayWithCapacity:views.count+1];for ( int i = 0 ; i < views.count+1 ; ++i ){ UIView *v = [UIView new]; [spaces addObject:v]; [self addSubview:v]; [v mas_makeConstraints:^(MASConstraintMaker *make) { make.width.equalTo(v.mas_height); }];} UIView *v0 = spaces[0];__weak __typeof(&*self)ws = self;[v0 mas_makeConstraints:^(MASConstraintMaker *make) { make.left.equalTo(ws.mas_left); make.centerY.equalTo(((UIView*)views[0]).mas_centerY);}];UIView *lastSpace = v0;for ( int i = 0 ; i < views.count; ++i ){ UIView *obj = views[i]; UIView *space = spaces[i+1]; [obj mas_makeConstraints:^(MASConstraintMaker *make) { make.left.equalTo(lastSpace.mas_right); }]; [space mas_makeConstraints:^(MASConstraintMaker *make) { make.left.equalTo(obj.mas_right); make.centerY.equalTo(obj.mas_centerY); make.width.equalTo(v0); }]; lastSpace = space;}[lastSpace mas_makeConstraints:^(MASConstraintMaker *make) { make.right.equalTo(ws.mas_right);}];
}
- (void) distributeSpacingVerticallyWith:(NSArray*)views { NSMutableArray *spaces = [NSMutableArray arrayWithCapacity:views.count+1];for ( int i = 0 ; i < views.count+1 ; ++i ){ UIView *v = [UIView new]; [spaces addObject:v]; [self addSubview:v]; [v mas_makeConstraints:^(MASConstraintMaker *make) { make.width.equalTo(v.mas_height); }];}UIView *v0 = spaces[0];__weak __typeof(&*self)ws = self;[v0 mas_makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(ws.mas_top); make.centerX.equalTo(((UIView*)views[0]).mas_centerX);}];UIView *lastSpace = v0;for ( int i = 0 ; i < views.count; ++i ){ UIView *obj = views[i]; UIView *space = spaces[i+1]; [obj mas_makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(lastSpace.mas_bottom); }]; [space mas_makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(obj.mas_bottom); make.centerX.equalTo(obj.mas_centerX); make.height.equalTo(v0); }]; lastSpace = space;}[lastSpace mas_makeConstraints:^(MASConstraintMaker *make) { make.bottom.equalTo(ws.mas_bottom);}];
}
@end代码如下:
UIView *sv11 = [UIView new];UIView *sv12 = [UIView new];UIView *sv13 = [UIView new];UIView *sv21 = [UIView new];UIView *sv31 = [UIView new];sv11.backgroundColor = [UIColor redColor];sv12.backgroundColor = [UIColor redColor];sv13.backgroundColor = [UIColor redColor];sv21.backgroundColor = [UIColor redColor];sv31.backgroundColor = [UIColor redColor];[sv addSubview:sv11];[sv addSubview:sv12];[sv addSubview:sv13];[sv addSubview:sv21];[sv addSubview:sv31];//给予不同的大小 测试效果[sv11 mas_makeConstraints:^(MASConstraintMaker *make) { make.centerY.equalTo(@[sv12,sv13]); make.centerX.equalTo(@[sv21,sv31]); make.size.mas_equalTo(CGSizeMake(40, 40));}];[sv12 mas_makeConstraints:^(MASConstraintMaker *make) { make.size.mas_equalTo(CGSizeMake(70, 20));}];[sv13 mas_makeConstraints:^(MASConstraintMaker *make) { make.size.mas_equalTo(CGSizeMake(50, 50));}];[sv21 mas_makeConstraints:^(MASConstraintMaker *make) { make.size.mas_equalTo(CGSizeMake(50, 20));}];[sv31 mas_makeConstraints:^(MASConstraintMaker *make) { make.size.mas_equalTo(CGSizeMake(40, 60));}];[sv distributeSpacingHorizontallyWith:@[sv11,sv12,sv13]];[sv distributeSpacingVerticallyWith:@[sv11,sv21,sv31]];[sv showPlaceHolderWithAllSubviews];[sv hidePlaceHolder];
转载地址:http://sfwci.baihongyu.com/