Coding源码学习第四部分(Masonry介绍与使用(二))
接上篇,本篇继续对Masonry 进行学习,接上篇示例:
(6)Masonry 布局实现iOS 计算器
1 - (void)exp4 { 2 WS(weakSelf); 3 // 申明区域,displayView 是显示布局,keyboardView 是键盘区域 4 UIView *displayView = [UIView new]; // 创建并添加 显示区域 5 [displayView setBackgroundColor:[UIColor blackColor]]; 6 [self.view addSubview:displayView]; 7 8 UIView *keyboardView = [UIView new]; 9 [self.view addSubview:keyboardView]; // 添加键盘区域 10 // 先按1:3分割 displayView (显示结果区域)和keyboardView (键盘区域) 11 [displayView mas_makeConstraints:^(MASConstraintMaker *make) { 12 make.top.equalTo(weakSelf.view.mas_top); 13 make.left.and.right.equalTo(weakSelf.view); // 顶部和左右 和self.view 相等 14 make.height.equalTo(keyboardView).multipliedBy(0.3f); // displayView 的高度是 keyboardView 的高度乘以 0.3 keyboardView 的高度是displayView 高度的三倍 15 }]; 16 17 [keyboardView mas_makeConstraints:^(MASConstraintMaker *make) { 18 make.top.equalTo(displayView.mas_bottom); // 键盘区域的top 紧接着显示结果区域的bottom 19 make.bottom.equalTo(weakSelf.view.mas_bottom); // 键盘区域的底部等于self.view 的底部 20 make.left.and.right.equalTo(weakSelf.view); // 左右相等 21 }]; 22 23 // 设置显示位置的数字为0 24 UILabel *displayNum = [[UILabel alloc] init]; 25 [displayView addSubview:displayNum]; 26 displayNum.text = @"0"; 27 displayNum.font = [UIFont fontWithName:@"HeiTi SC" size:70]; // 设置字体 @"HeiTi SC" 28 displayNum.textColor = [UIColor whiteColor]; 29 displayNum.textAlignment = NSTextAlignmentRight; 30 [displayNum mas_makeConstraints:^(MASConstraintMaker *make) { 31 make.left.and.right.equalTo(displayView).with.offset(-10); // 左和右各缩进 10 32 make.bottom.equalTo(displayView).with.offset(-10); // 底部也缩进 10 // label 的高度能根据label 的内容自动适应高度 只要确定一个底部或者顶部就能确定label 的约束 label 的宽度要确定才能确定高度 33 }]; 34 // 定义键盘键名称,? 号代表合并的单元格 35 NSArray *keys = @[@"AC", @"+/-", @"%", @"÷" 36 , @"7", @"8", @"9", @"x" 37 , @"4", @"5", @"6", @"-" 38 , @"1", @"2", @"3", @"+" 39 , @"0", @"?", @".", @"="]; 40 int indexOfKeys = 0; 41 for (NSString *key in keys) { 42 // 循环所有键 43 indexOfKeys++; 44 int rowNum = indexOfKeys % 4 == 0 ? indexOfKeys / 4 : indexOfKeys / 4 + 1; // 求各个key 的行和列 注意是从 1 开始的 求行的时候, 先对 4 取余数, 如果是 0 的话正好是 4 的倍数 ,那就是最后一列的key indexOfKeys 这个时候是 4 或 8 或 12 或 16 或 20 , 这个时候取 indexOfKeys 的商正好是key 所在的行 ,其他的同理 45 int colNum = indexOfKeys % 4 == 0 ? 4 : indexOfKeys % 4; 46 NSLog(@"index is: %d and row: %d, col: %d", indexOfKeys, rowNum, colNum); 47 // 键样式 48 UIButton *keyView = [UIButton buttonWithType:UIButtonTypeCustom]; 49 [keyboardView addSubview:keyView]; 50 [keyView setTitleColor:[UIColor blackColor] forState:UIControlStateNormal]; 51 [keyView setTitle:key forState:UIControlStateNormal]; 52 [keyView.layer setBorderWidth:1]; 53 [keyView.layer setBorderColor:[UIColor blackColor].CGColor]; 54 [keyView.titleLabel setFont:[UIFont fontWithName:@"Arial-BoldItalicMT" size:30]]; // 设置字体 @"Arial-BoldItalicMT" 55 // 键约束 56 [keyView mas_makeConstraints:^(MASConstraintMaker *make) { 57 // 处理 0 合并单元格 58 if ([key isEqualToString:@"0"] || [key isEqualToString:@"?"]) { 59 if ([key isEqualToString:@"0"]) { 60 [keyView mas_makeConstraints:^(MASConstraintMaker *make) { 61 make.height.equalTo(keyboardView.mas_height).with.multipliedBy(.2f); // 高度是keyboardView 的高度的五分之一 62 make.width.equalTo(keyboardView.mas_width).multipliedBy(.5); // 宽度是keyboardView 的宽度的二分之一 63 make.left.equalTo(keyboardView.mas_left); // 左边相等 64 make.baseline.equalTo(keyboardView.mas_baseline).with.multipliedBy(.9f); // 这个baseline 没有看太懂是什么意思 65 }]; 66 } if ([key isEqualToString:@"?"]) { // 如果是问号的话直接被移除了 67 [keyView removeFromSuperview]; 68 } 69 } 70 // 正常的单元格 71 else { 72 make.width.equalTo(keyboardView.mas_width).with.multipliedBy(.25f); // 正常的单元格的话 宽度是 keyboardView 的宽度的四分之一 73 make.height.equalTo(keyboardView.mas_height).with.multipliedBy(.2f); // 高度是keyboardView 的高度的五分之一 74 // 按照行和列添加约束,这里添加行约束 75 switch (rowNum) { 76 case 1: 77 { 78 make.baseline.equalTo(keyboardView.mas_baseline).with.multipliedBy(.1f); 79 keyView.backgroundColor = [UIColor colorWithRed:205 green:205 blue:205 alpha:1]; 80 } 81 break; 82 case 2: 83 { 84 make.baseline.equalTo(keyboardView.mas_baseline).with.multipliedBy(.3f); 85 } 86 break; 87 case 3: 88 { 89 make.baseline.equalTo(keyboardView.mas_baseline).with.multipliedBy(.5f); 90 } 91 break; 92 case 4: 93 { 94 make.baseline.equalTo(keyboardView.mas_baseline).with.multipliedBy(.7f); 95 } 96 break; 97 case 5: 98 { 99 make.baseline.equalTo(keyboardView.mas_baseline).with.multipliedBy(.9f); 100 } 101 break; 102 default: 103 break; 104 } 105 switch (colNum) { 106 case 1: 107 { 108 make.left.equalTo(keyboardView.mas_left); 109 } 110 break; 111 case 2: 112 { 113 make.right.equalTo(keyboardView.mas_centerX); 114 } 115 break; 116 case 3: 117 { 118 make.left.equalTo(keyboardView.mas_centerX); 119 } 120 break; 121 case 4: 122 { 123 make.right.equalTo(keyboardView.mas_right); 124 [keyView setBackgroundColor:[UIColor colorWithRed:243 green:127 blue:38 alpha:1]]; 125 } 126 break; 127 default: 128 break; 129 } 130 } 131 }]; 132 } 133 }
(7)基础设计页面
1 - (void)HYB { 2 UIView *greenView = UIView.new; 3 greenView.backgroundColor = UIColor.greenColor; 4 greenView.layer.borderColor = UIColor.blackColor.CGColor; 5 greenView.layer.borderWidth = 2; 6 [self.view addSubview:greenView]; 7 8 UIView *redView = UIView.new; 9 redView.backgroundColor = UIColor.redColor; 10 redView.layer.borderColor = UIColor.blackColor.CGColor; 11 redView.layer.borderWidth = 2; 12 [self.view addSubview:redView]; 13 14 UIView *blueView = UIView.new; 15 blueView.backgroundColor = UIColor.blueColor; 16 blueView.layer.borderColor = UIColor.blackColor.CGColor; 17 blueView.layer.borderWidth = 2; 18 [self.view addSubview:blueView]; 19 20 // 使三个控件等高 21 CGFloat padding = 10; 22 [greenView mas_makeConstraints:^(MASConstraintMaker *make) { 23 make.top.mas_equalTo(padding); 24 make.left.mas_equalTo(padding); 25 make.right.mas_equalTo(redView.mas_left).offset(-padding); 26 make.bottom.mas_equalTo(blueView.mas_top).offset(-padding); 27 // 三个控件等高 28 make.height.mas_equalTo(@[redView, blueView]); 29 // 红绿这两个控件等宽 30 make.width.mas_equalTo(redView); 31 }]; 32 33 [redView mas_makeConstraints:^(MASConstraintMaker *make) { 34 make.top.height.bottom.mas_equalTo(greenView); 35 make.right.mas_equalTo(-padding); 36 make.left.mas_equalTo(greenView.mas_right).offset(padding); 37 }]; 38 39 [blueView mas_makeConstraints:^(MASConstraintMaker *make) { 40 make.height.mas_equalTo(greenView); 41 make.bottom.mas_equalTo(-padding); 42 make.left.mas_equalTo(padding); 43 make.right.mas_equalTo(-padding); 44 }]; 45 }
约束使用链式方式,使用方法很简单,看起来像一句话。
看这句话:make.top.height.bottom.mas_equalTo(greenView)
,意思是:使我的顶部、高度和底部都与greenView
的顶部、高度和底部相等。因此,只要greenView
的约束添加好了,那么redView
的顶部、高度和底部也就自动计算出来了。
大多时候,我们并不会将一句话完整地写出来,而是使用简写的方式。
如:make.right.mas_equalTo(-padding);
其完整的写法为:
make.right.mas_equalTo(bludView.superView.mas_right).offset(-padding);
当我们是要与父控件相对约束时,可以省略掉父视图。注意,并不是什么时候都可以省略,只有约束是同样的才可以省略。比如,约束都是right
才可以。如果是一个left
一个是right
,那么就不能省略了。当然如果是两个不同的控件也是不能省略的。
(8)动画的形式更新约束(Masonry 以动画的形式更新约束,初始一个很小的按钮,点击就不断放大,最大就放大到全屏幕)
1 #import "ViewController.h" 2 #import "Masonry.h" 3 4 #define WS(weakSelf) __weak __typeof(&*self) weakSelf = self; 5 6 @interface ViewController () 7 8 @property(nonatomic, strong) UIButton *growingButton; 9 @property(nonatomic, assign) CGFloat scacle; 10 11 @end 12 13 @implementation ViewController 14 15 - (void)viewDidLoad { 16 [super viewDidLoad]; 17 // 动画更新约束 18 WS(weakSelf); 19 self.growingButton = [UIButton buttonWithType:UIButtonTypeSystem]; 20 [self.growingButton setTitle:@"点我放大" forState:UIControlStateNormal]; 21 self.growingButton.layer.borderColor = UIColor.greenColor.CGColor; 22 self.growingButton.layer.borderWidth = 3; 23 [self.growingButton addTarget:self action:@selector(onGrowButtonTaped:) forControlEvents:UIControlEventTouchUpInside]; 24 [self.view addSubview:self.growingButton]; 25 26 self.scacle = 1.0; 27 28 [self.growingButton mas_makeConstraints:^(MASConstraintMaker *make) { 29 make.center.mas_equalTo(weakSelf.view); 30 // 初始宽、高为100,优先级最低 31 make.width.height.mas_equalTo(100 * weakSelf.scacle).priorityLow(); 32 // 最大放大到整个View 33 make.width.height.lessThanOrEqualTo(weakSelf.view); 34 }]; 35 } 36 37 38 #pragma mark - updateViewConstraints 39 - (void)updateViewConstraints { 40 WS(weakSelf); 41 [self.growingButton mas_updateConstraints:^(MASConstraintMaker *make) { 42 make.center.mas_equalTo(weakSelf.view); 43 // 初始宽高为100 优先级最低 44 make.width.height.mas_equalTo(100 * weakSelf.scacle).priorityLow(); 45 // 最大放大到整个View 46 make.width.height.lessThanOrEqualTo(weakSelf.view); 47 }]; 48 49 [super updateViewConstraints]; 50 } 51 52 53 - (void)onGrowButtonTaped:(UIButton *)sender { 54 WS(weakSelf); 55 self.scacle += 0.5; // 一次增加 0.5 倍 56 // 告诉self.view 约束需要更新 57 [self.view setNeedsUpdateConstraints]; 58 // 调用此方法告诉self.view 检测是否需要更新约束,若需要则更新,下面添加动画效果才起作用 59 [self.view updateConstraintsIfNeeded]; 60 61 [UIView animateWithDuration:0.3 animations:^{ 62 [weakSelf.view layoutIfNeeded]; 63 }]; 64 }
[self.growingButton mas_makeConstraints:^(MASConstraintMaker *make) {
make.center.mas_equalTo(weakSelf.view);
// 初始宽、高为100,优先级最低
make.width.height.mas_equalTo(100 * weakSelf.scacle).priorityLow(); // 让控件的宽和高相等且优先级最低。关于优先级,后面再讲
// 最大放大到整个View
make.width.height.lessThanOrEqualTo(weakSelf.view); // 让控件的宽和高小于或者等于self.view 的宽和高, 因此这个控件的最多能放大到全屏幕
}];
将这三行代码放在一起,形成的话就是:使控件与父视图始终保持居中,控件的宽和高最大不能超过屏幕,且控件的宽和高可以变化。由于我们设置了第二行的代码优先级为priorityLow,因此其优先级是最低的,所以就可以保证宽高不能超过屏幕。 其实,当我们将更新代码放到updateViewConstraints这个方法中时,这些约束就不需要了,这里写上去的目的只是想说明用于不用都没有关系。
// 告诉self.view 约束需要更新
看下面的方法,就是动画更新约束的核心代码:
[self.view setNeedsUpdateConstraints];
// 想要更新约束时添加动画,就需要调用关键的一行代码:setNeedsUpdateConstraints,这是选择对应的视图中的约束需要更新
// 调用此方法告诉self.view 检测是否需要更新约束,若需要则更新,下面添加动画效果才起作用
[self.view updateConstraintsIfNeeded];
// 对于updateConstraintsIfNeeded这个方法并不是必须的,但是有时候不调用就无法起到我们的效果。但是,官方都是这么写的,从约束的更新原理上讲,这应该写上。我们要使约束立即生效,就必须调用layoutIfNeeded此方法,[UIView animateWithDuration:0.3 animations:^{ [self.view layoutIfNeeded]; }];
(9)移除约束
1 #import "RemakeContraintsViewController.h" 2 #import "Masonry.h" 3 4 @interface RemakeContraintsViewController () 5 6 @property(nonatomic, strong) UIButton *growingButton; 7 @property(nonatomic, assign) BOOL isExpanded; 8 9 @end 10 11 @implementation RemakeContraintsViewController 12 13 - (void)viewDidLoad { 14 [super viewDidLoad]; 15 // Do any additional setup after loading the view. 16 self.view.backgroundColor = [UIColor whiteColor]; 17 18 self.growingButton = [UIButton buttonWithType:UIButtonTypeSystem]; 19 [self.growingButton setTitle:@"点我展开" forState:UIControlStateNormal]; 20 self.growingButton.layer.borderColor = UIColor.greenColor.CGColor; 21 self.growingButton.layer.borderWidth = 3; 22 self.growingButton.backgroundColor = [UIColor redColor]; 23 [self.growingButton addTarget: self action:@selector(onGrowButtonTaped:) forControlEvents:UIControlEventTouchUpInside]; 24 [self.view addSubview:self.growingButton]; 25 self.isExpanded = NO; 26 } 27 28 - (void)updateViewConstraints { 29 // 这里使用update 也是一样的 30 // remake 会将之前的全部移除, 然后重新添加 31 [self.growingButton mas_remakeConstraints:^(MASConstraintMaker *make) { 32 make.top.mas_equalTo(0); 33 make.left.right.mas_equalTo(0); 34 if (self.isExpanded) { 35 make.bottom.mas_equalTo(0); 36 } else { 37 make.bottom.mas_equalTo(-350); 38 } 39 }]; 40 41 [super updateViewConstraints]; 42 } 43 44 - (void)onGrowButtonTaped:(UIButton *)sender { 45 self.isExpanded = !self.isExpanded; 46 if (!self.isExpanded) { 47 [self.growingButton setTitle:@"点我展开" forState:UIControlStateNormal]; 48 } else { 49 [self.growingButton setTitle:@"点我收起" forState:UIControlStateNormal]; 50 } 51 // 告诉self.view 约束需要更新 52 [self.view setNeedsUpdateConstraints]; 53 // 调用此方法告诉self.view 检测是否需要更新,若需要则更新,下面添加动画效果才起作用 54 [self.view updateConstraintsIfNeeded]; 55 56 [UIView animateWithDuration:0.3 animations:^{ 57 [self.view layoutIfNeeded]; 58 }]; 59 }
(10)整体动画更新约束
1 #import "TotalUpdateViewController.h" 2 #import "Masonry.h" 3 4 @interface TotalUpdateViewController () 5 6 @property(nonatomic, strong) UIView *purpleView; 7 @property(nonatomic, strong) UIView *orangeView; 8 @property(nonatomic, assign) BOOL isExpaned; 9 10 @end 11 12 @implementation TotalUpdateViewController 13 14 - (void)viewDidLoad { 15 [super viewDidLoad]; 16 // Do any additional setup after loading the view. 17 self.view.backgroundColor = [UIColor whiteColor]; 18 19 UIView *purpleView = [[UIView alloc] init]; 20 purpleView.backgroundColor = UIColor.purpleColor; 21 purpleView.layer.borderColor = UIColor.blackColor.CGColor; 22 purpleView.layer.borderWidth = 2; 23 [self.view addSubview:purpleView]; 24 25 UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onTap)]; 26 [purpleView addGestureRecognizer:tap]; 27 self.purpleView = purpleView; 28 29 UIView *orangeView = UIView.new; 30 orangeView.backgroundColor = UIColor.orangeColor; 31 orangeView.layer.borderColor = UIColor.blackColor.CGColor; 32 orangeView.layer.borderWidth = 2; 33 [self.view addSubview:orangeView]; 34 self.orangeView = orangeView; 35 36 // 这里,我们不使用updateViewConstraints 方法,但是我们一样可以做到 37 // 不过苹果推荐在updateViewConstraints 方法中更新约束或者添加约束 38 [self updateWithExpand:NO animated:NO]; 39 40 UILabel *label = [[UILabel alloc] init]; 41 label.numberOfLines = 0; 42 label.textColor = [UIColor redColor]; 43 label.font = [UIFont systemFontOfSize:16]; 44 label.textAlignment = NSTextAlignmentCenter; 45 label.text = @"点击purple 部分放大,orange 部分最大值 250 ,最小值 90 "; 46 [self.purpleView addSubview:label]; 47 48 [label mas_makeConstraints:^(MASConstraintMaker *make) { 49 make.bottom.mas_equalTo(0); // 0 就是和底部相等 50 make.left.right.mas_equalTo(0); 51 }]; 52 } 53 54 - (void)updateWithExpand:(BOOL)isExpanded animated:(BOOL)animated { 55 self.isExpaned = isExpanded; 56 57 [self.purpleView mas_updateConstraints:^(MASConstraintMaker *make) { // 更新紫色的约束 58 make.left.top.mas_equalTo(20); 59 make.right.mas_equalTo(-20); // 右边和底部 0 是相等 小于0 的是缩进 大于的0 的是伸展 而左边和顶部正好相反 60 if (isExpanded) { 61 make.bottom.mas_equalTo(-20); 62 } else { 63 make.bottom.mas_equalTo(-300); 64 } 65 }]; 66 67 [self.orangeView mas_updateConstraints:^(MASConstraintMaker *make) { // 更新橙色的约束 68 make.center.mas_equalTo(self.purpleView); 69 // 这里使用优先级处理 70 // 设置其最大值为 250 ,最小值为 90 71 if (!isExpanded) { 72 make.width.height.mas_equalTo(100 * 0.5).priorityLow(); 73 } else { 74 make.width.height.mas_equalTo(100 * 3).priorityLow(); 75 } 76 77 // 最大值为 250 78 make.width.height.lessThanOrEqualTo(@250); 79 // 最小值为90 80 make.width.height.greaterThanOrEqualTo(@90); 81 }]; 82 83 if (animated) { 84 [self.view setNeedsUpdateConstraints]; 85 [self.view updateConstraintsIfNeeded]; 86 87 [UIView animateWithDuration:0.5 animations:^{ 88 [self.view layoutIfNeeded]; 89 }]; 90 } 91 } 92 93 - (void)onTap { 94 [self updateWithExpand:!self.isExpaned animated:YES]; 95 }
展开与收起的关键代码在这里.设置最大最小值,这样就不会超出我们预期的范围。
// 最大值为250
make.width.height.lessThanOrEqualTo(@250);
// 最小值为90
make.width.height.greaterThanOrEqualTo(@90);
我们设置其固定的宽高,并且设置其优先级为最低,以保证我们所设置的最大最小值始终生效。
想要更新约束时添加动画,就需要调用关键的一行代码:setNeedsUpdateConstraints
,这是选择对应的视图中的约束需要更新。
对于updateConstraintsIfNeeded
这个方法并不是必须的,但是有时候不调用就无法起到我们的效果。但是,官方都是这么写的,从约束的更新原理上讲,这应该写上。我们要使约束立即生效,就必须调用layoutIfNeeded
此方法。下面的方法,就是动画更新约束的核心代码:
1 if (animated) { 2 // 告诉self.view 约束需要更新 3 [self.view setNeedsUpdateConstraints]; 4 // 调用此方法告诉self.view 检测是否需要更新约束,若需要则更新,下面添加动画效果才起作用 5 [self.view updateConstraintsIfNeeded]; 6 7 [UIView animateWithDuration:0.5 animations:^{ 8 [self.view layoutIfNeeded]; 9 }]; 10 }
(11)比例(multipliedBy)
1 // 首先创建4 个的View 视图 顶部和底部的View 平分屏幕 2 // 顶部View 红色 3 UIView *topView = [UIView new]; 4 topView.backgroundColor = [UIColor redColor]; 5 [self.view addSubview:topView]; 6 // 顶部内部的View 绿色 7 UIView *topInnerView = [UIView new]; 8 topInnerView.backgroundColor = [UIColor greenColor]; 9 [topView addSubview:topInnerView]; 10 // 底部View 11 UIView *bottomView = [UIView new]; 12 bottomView.backgroundColor = [UIColor blackColor]; 13 [self.view addSubview:bottomView]; 14 // 底部内部的View 蓝色 15 UIView *bottomInnerView = [UIView new]; 16 bottomInnerView.backgroundColor = [UIColor blueColor]; 17 [bottomView addSubview:bottomInnerView]; 18 19 [topView mas_makeConstraints:^(MASConstraintMaker *make) { 20 make.left.right.top.mas_equalTo(0); // 上左右 等于 0 21 make.height.mas_equalTo(bottomView); // 高度两者相等 22 }]; 23 24 // width = height / 3 25 [topInnerView mas_makeConstraints:^(MASConstraintMaker *make) { 26 make.left.right.mas_equalTo(topView); // 左右相等 27 make.width.mas_equalTo(topInnerView.mas_height).multipliedBy(3); // topInnerView 的宽度等于高度乘以3 28 make.center.mas_equalTo(topView); // 中心重合 29 30 // 设置优先级 31 make.width.height.mas_equalTo(topView).priorityLow(); 32 make.width.height.lessThanOrEqualTo(topView); // 宽度和高度最大也比topView 小于等于 33 }]; 34 35 [bottomView mas_makeConstraints:^(MASConstraintMaker *make) { 36 make.left.right.bottom.mas_equalTo(0); // 左右底等于0 37 make.height.mas_equalTo(topView); // 高度和topView 相等 38 make.top.mas_equalTo(topView.mas_bottom); // top 等于 topView 的bottom 39 }]; 40 41 // width / height / 比为 1 / 3.0 要求是同一个控件的属性比例 42 [bottomInnerView mas_makeConstraints:^(MASConstraintMaker *make) { 43 make.top.bottom.mas_equalTo(bottomView); // 顶部和底部等于bottomView 的顶部和底部 44 make.center.mas_equalTo(bottomView); // 中心相等 45 // 注意,这个multipliedBy 的使用只能是设置同一个控件,比如这里的bottonInnerView 46 // 设置高 / 宽 为 3:1 47 make.height.mas_equalTo(bottomInnerView.mas_width).multipliedBy(3); // 高度等于宽度乘以 3 48 49 make.width.height.mas_equalTo(bottomView).priorityLow(); // 宽和高设置优先级 50 make.width.height.lessThanOrEqualTo(bottomView); // 宽度和高度最高也小于bottomView 的高度和宽度 51 }];
1 [topInnerView mas_makeConstraints:^(MASConstraintMaker *make) { 2 make.left.right.mas_equalTo(topView); // 左右相等 3 make.width.mas_equalTo(topInnerView.mas_height).multipliedBy(3); // topInnerView 的宽度等于高度乘以3 4 make.center.mas_equalTo(topView); // 中心重合 5 6 // 设置优先级 7 make.width.height.mas_equalTo(topView).priorityLow(); 8 make.width.height.lessThanOrEqualTo(topView); // 宽度和高度最大也比topView 小于等于 9 }];
提示:使用multipliedBy
必须是对同一个控件本身,比如,上面的代码中,我们都是对bottomInnerView.mas_width
本身的,如果修改成相对于其它控件,会出问题。
bottomInnerView
的约束如何添加。 希望width/height
比为1/3.0
,首先,设置了其top
和bottom
与父视图一致且始终在父视图中居中显示,设置了bottomInnerView
的高为宽的3倍,然后设置了宽和高与父视图相等,但是优先级为最低,以保证子视图的宽高不超过父视图,然后通过make.width.height.lessThanOrEqualTo
设置了宽、高的最大值与父视图相同,:
1 // width / height / 比为 1 / 3.0 要求是同一个控件的属性比例 2 [bottomInnerView mas_makeConstraints:^(MASConstraintMaker *make) { 3 make.top.bottom.mas_equalTo(bottomView); // 顶部和底部等于bottomView 的顶部和底部 4 make.center.mas_equalTo(bottomView); // 中心相等 5 // 注意,这个multipliedBy 的使用只能是设置同一个控件,比如这里的bottonInnerView 6 // 设置高 / 宽 为 3:1 7 make.height.mas_equalTo(bottomInnerView.mas_width).multipliedBy(3); // 高度等于宽度乘以 3 8 9 make.width.height.mas_equalTo(bottomView).priorityLow(); // 宽和高设置优先级 10 make.width.height.lessThanOrEqualTo(bottomView); // 宽度和高度最高也小于bottomView 的高度和宽度 11 }];
接下篇...