概念简述
约束优先级: 在Autolayout中每个约束都有一个优先级, 优先级的范围是1 ~ 1000。创建一个约束,默认的优先级是最高的1000;Content Hugging Priority: 该优先级表示一个控件抗被拉伸的优先级。优先级越高,越不容易被拉伸,默认是250(UILayoutPriorityDefaultLow)。
Content Compression Resistance Priority: 该优先级和上面那个优先级相对应,表示一个控件抗压缩的优先级。优先级越高,越不容易被压缩,默认是750(UILayoutPriorityDefaultHigh);
通过以下两个方法来设置他们的抗被拉伸的优先级和抗压缩的优先级:
- (void)setContentCompressionResistancePriority:(UILayoutPriority)priority forAxis:(UILayoutConstraintAxis)axis API_AVAILABLE(ios(6.0)); - (void)setContentHuggingPriority:(UILayoutPriority)priority forAxis:(UILayoutConstraintAxis)axis;
优先级取值:
static const UILayoutPriority UILayoutPriorityRequired = 1000; static const UILayoutPriority UILayoutPriorityDefaultHigh = 750; static const UILayoutPriority UILayoutPrioritySceneSizeStayPut = 500; static const UILayoutPriority UILayoutPriorityDefaultLow = 250; static const UILayoutPriority UILayoutPriorityFittingSizeLevel = 50;
场景一
- (void)test { UILabel *leftLabel = [UILabel new]; leftLabel.text = @"我是左边我是我是左边"; leftLabel.backgroundColor = [UIColor redColor]; [self.view addSubview:leftLabel]; UILabel *rightLabel = [UILabel new]; rightLabel.text = @"评论数:20"; rightLabel.backgroundColor = [UIColor yellowColor]; [self.view addSubview:rightLabel]; [leftLabel mas_makeConstraints:^(MASConstraintMaker *make) { make.top.mas_equalTo(100); make.left.mas_equalTo(10); }]; [rightLabel mas_makeConstraints:^(MASConstraintMaker *make) { make.left.equalTo(leftLabel.mas_right).offset(10); make.right.mas_equalTo(-10); make.top.equalTo(leftLabel.mas_top); }]; }
默认显示效果如图
如果希望左边的自适应,右边的自动填充,那么我们需要增大左边的抗被拉伸优先级(越大越不容易被拉伸,默认250、UILayoutPriorityDefaultLow),或者减小右边的抗被拉伸优先级,这样才能让右边的label内容优先显示。
增加以下代码设置:
[leftLabel setContentHuggingPriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisHorizontal];
或者
[rightLabel setContentHuggingPriority:UILayoutPriorityFittingSizeLevel forAxis:UILayoutConstraintAxisHorizontal];
显示效果
在增加上述的代码以后如果增加左边的文字,效果如下:
此时发现右边的文字无法显示了,继续向下分析;
场景二
- (void)test { UILabel *leftLabel = [UILabel new]; leftLabel.text = @"我是左边我是左边我是左边我是左边我是左边我是左边我是左边我是左边我是左边"; leftLabel.backgroundColor = [UIColor redColor]; [self.view addSubview:leftLabel]; UILabel *rightLabel = [UILabel new]; rightLabel.text = @"评论数:20"; rightLabel.backgroundColor = [UIColor yellowColor]; [self.view addSubview:rightLabel]; [leftLabel mas_makeConstraints:^(MASConstraintMaker *make) { make.top.mas_equalTo(100); make.left.mas_equalTo(10); }]; [rightLabel mas_makeConstraints:^(MASConstraintMaker *make) { make.left.equalTo(leftLabel.mas_right).offset(10); make.right.mas_equalTo(-10); make.top.equalTo(leftLabel.mas_top); }]; }
左边内容多超过屏幕,默认显示效果如图
如果希望右边完全显示,左边内容自适应,那么我们需要增大右边的抗压缩优先级(优先级越高,越不容易被压缩,默认750、UILayoutPriorityDefaultHigh),或者减少左边的抗压缩优先级;
增加以下代码设置:
[leftLabel setContentCompressionResistancePriority:UILayoutPriorityDefaultLow forAxis:UILayoutConstraintAxisHorizontal];
或者
[rightLabel setContentCompressionResistancePriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisHorizontal]
显示效果
在增加上述的代码以后如果,减少左边的文字,效果如下:
场景三
需求:
- 黄色内容完全展示并且在红色右边,并且间距始终为10
- 红色内容少的时候自适应、内容多的时候显示...
解决方案:
这个时候需要将场景一和场景2的内容同时使用,也就是同时使用抗压缩和抗拉伸优先级:
[leftLabel setContentHuggingPriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisHorizontal]; [rightLabel setContentCompressionResistancePriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisHorizontal]
或者
[rightLabel setContentHuggingPriority:UILayoutPriorityFittingSizeLevel forAxis:UILayoutConstraintAxisHorizontal]; [leftLabel setContentCompressionResistancePriority:UILayoutPriorityDefaultLow forAxis:UILayoutConstraintAxisHorizontal];
即场景一和场景二中的代码任性其一进行组合,这里只列出了2种;
运行效果1(左边内容多的时候):
运行效果2(左边内容少的时候):
总结
- 空间充足的情况下,可以设置某个控件的抗被拉伸优先级,让某个控件或其余控件占用剩余空间;
- 空间不足的情况下,可以设置某个控件的抗压缩优先级,让某个控件展示完全;