1.Masonry实现自定义UITableViewCell的自适应高度。
原理:模板单元格中,subviews的自动局部必须要能够把单元格撑满。也就是说,iOS 必须能够通过内容的自动布局约束计算出 cell 的高。 简单点讲,cell的高度由每个subView的高度和他们之间的间距组成,subView的高度由Masonry负责,他们之间的距离由我们负责,这样就能实现自适应高度。
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
[self.contentView addSubview:self.topLabel];
[self.contentView addSubview:self.centerLabel];
[self.contentView addSubview:self.bottomLabel];
[self.topLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.left.equalTo(self.contentView).offset(20);
make.right.equalTo(self.contentView).offset(-20);
}];
[self.centerLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.topLabel.mas_bottom).offset(30);
make.left.equalTo(self.contentView).offset(15);
make.right.equalTo(self.contentView).offset(-30);
}];
[self.bottomLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.centerLabel.mas_bottom).offset(10);
make.left.equalTo(self.contentView).offset(35);
make.right.equalTo(self.contentView).offset(-35);
make.bottom.equalTo(self.contentView).offset(-30);
}];
}
return self;
}
复制代码
- topLabel的top距cell的top为20。
- centerLabel的top距topLabel的bottom为30。
- bottomLabel的top距centerLabel的bottom为10。
- bottomLabel的bottom距cell的bottom为30。
- 这样cell的top和bottom就连在一起了。
self.tableView.rowHeight = UITableViewAutomaticDimension; //设置动态行高
self.tableView.estimatedRowHeight = 50; //设置预估高度
复制代码
这样就实现了cell的自适应高度
2.Masonry解决压缩优先级问题
如上图所示,有时候我们需要在一个cell里面设置左右2个label,但label的长度是不清楚的,如果我们按下面这样布局,在label短的时候是没有问题的,一旦碰到label过长,就会产生各种情况,例如上图,直接被挤不见了。[self.leftTop mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.left.equalTo(self.contentView).offset(20);
}];
[self.rightTop mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.contentView).offset(20);
make.right.equalTo(self.contentView).offset(-20);
make.left.equalTo(self.leftTop.mas_right).offset(20);
}];
复制代码
为了解决这个问题,就要用到压缩优先级,简单点讲,压缩优先级越高,越不容易被压缩,在碰到要压缩的情况下先保证压缩优先级高的对象。
设置压缩优先级得用到这个方法。
- (void)setContentCompressionResistancePriority:(UILayoutPriority)priority forAxis:(UILayoutConstraintAxis)axis NS_AVAILABLE_IOS(6_0);
复制代码
他需要传入2个值,第一个值UILayoutPriority
点进去观察.
typedef float UILayoutPriority NS_TYPED_EXTENSIBLE_ENUM;
static const UILayoutPriority UILayoutPriorityRequired NS_AVAILABLE_IOS(6_0) = 1000; //设置优先级为1000,为最高优先级。不能超过1000,超过了就没有效果了。
static const UILayoutPriority UILayoutPriorityDefaultHigh NS_AVAILABLE_IOS(6_0) = 750; // 设置优先级为750,这个优先级为高。
static const UILayoutPriority UILayoutPriorityDefaultLow NS_AVAILABLE_IOS(6_0) = 250; // 设置优先级为250,这个优先级为低。
static const UILayoutPriority UILayoutPriorityFittingSizeLevel NS_AVAILABLE_IOS(6_0) = 50; // 设置优先级50,这个优先级已经很低。
// 优先级越低越容易被压缩,基本上设置一个最高,一个低就能解决问题。
复制代码
第二个值UILayoutConstraintAxis
typedef NS_ENUM(NSInteger, UILayoutConstraintAxis) {
UILayoutConstraintAxisHorizontal = 0, // 水平的
UILayoutConstraintAxisVertical = 1 // 垂直的
};
复制代码
接着写代码
[self.leftTop setContentCompressionResistancePriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisHorizontal];
[self.rightTop setContentCompressionResistancePriority:UILayoutPriorityDefaultLow forAxis:UILayoutConstraintAxisHorizontal];
复制代码
发现已经正常显示了,而且被压缩的也是右边的部分。
但是在右边label长度不长的情况下就会产生这个情况。
作为一个拥有代码洁癖+强迫症的人,拒不允许有这样的东西出现。 这时候就得靠Masonry的另外2个属性了。greaterThanOrEqualTo
和
lessThanOrEqualTo
。 这2个属性大家肯定都见过,但不常用。
greaterThanOrEqualTo
大于或者等于。
lessThanOrEqualTo
小于或者等于。 贴代码
[self.leftTop mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.left.equalTo(self.contentView).offset(20);
}];
[self.rightTop mas_makeConstraints:^(MASConstraintMaker *make){
make.top.equalTo(self.contentView).offset(20);
make.right.equalTo(self.contentView).offset(-20);
make.left.greaterThanOrEqualTo(self.leftTop.mas_right).offset(20);
}];
复制代码
这样就成功解决了。 持续更新中~