使用Masonry的各种姿势

我们知道每次使用Masonry布局其最终结果就像上图所示,每个对象的大小都会由他的top.left.bottom.right距另一个对象的距离所决定。所以我们的一切操作就是为了给对象一个合适的距离。

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个属性了。 greaterThanOrEqualTolessThanOrEqualTo。 这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);
}];
复制代码

这样就成功解决了。 持续更新中~

Demo

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值