iOS_Masory布局踩坑

一、源起

最近在使用Masory做动态布局的时候,发现一个问题。
首先列举下我的当时的做法。

做法一。
在Cell的复用方法里添加子控件

-(instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
    if (self =[super initWithStyle:style reuseIdentifier:reuseIdentifier]) {

        [self.contentView addSubview:self.oneLabel];
        [self.contentView addSubview:self.TwoImageView];
    }
    return  self;
}

在layoutSubviews方法里面进行约束设置 当然懒加载的代码就不多写了
这里的需求是前面一个label 后面一个imageView 同行显示。imageView的X需要由label内容来确定。

-(void)layoutSubviews {
  [super ayoutSubviews];
//这里设置约束代码
[self.oneLabel mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.equalTo(self.contentView).offset(16);
        make.top.equalTo(self.contentView).offset(20);
        make.height.mas_equalTo(24);
    }];
    
    [self.TwoImageView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.equalTo(self.oneLabel).offset(4);;
        make.width..mas_equalTo(56);
       make.height.mas_equalTo(17);
       make.center.equalTo(self.oneLabel);
    }];
}

给cell赋值model 并重新设置约束

-(void)setModel:(Model*)model {
  self.oneLabel.text = @"这里做一个测试数据的展示";  
  //这里设置约束代码
//更新约束
[self.oneLabel update_makeConstraints:^(MASConstraintMaker *make) {
        make.left.equalTo(self.contentView).offset(16);
        make.top.equalTo(self.contentView).offset(20);
        make.height.mas_equalTo(24);
    }];
    
    [self.TwoImageView update_makeConstraints:^(MASConstraintMaker *make) {
        make.left.equalTo(self.oneLabel).offset(4);;
        make.width..mas_equalTo(56);
       make.height.mas_equalTo(17);
       make.center.equalTo(self.oneLabel);
    }];
}

以上方式出来之后 发现oneLabel不显示。TwoImageView显示错位了。

尝试修改一:

[self.oneLabel re_makeConstraints:^(MASConstraintMaker *make) {
        make.left.equalTo(self.contentView).offset(16);
        make.top.equalTo(self.contentView).offset(20);
        make.height.mas_equalTo(24);
    }];
    
    [self.TwoImageView re_makeConstraints:^(MASConstraintMaker *make) {
        make.left.equalTo(self.oneLabel.mas_right).offset(4);;
        make.width..mas_equalTo(56);
       make.height.mas_equalTo(17);
       make.center.equalTo(self.oneLabel);
    }];
}

仍旧无效,并且控制台不断输出约束报错信息。

尝试修改二:

-(void)layoutSubviews {
  [super ayoutSubviews];
//这里设置约束代码
[self.oneLabel mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.equalTo(self.contentView).offset(16);
        make.top.equalTo(self.contentView).offset(20);
        make.height.mas_equalTo(24);
    }];
   /去掉设置imageView的约束 等到拿到数据后在重新设置。
}

仍然无效。还是oneLabel还是不显示。

尝试修改三:
在赋值处修改用frame给self.TwoImageView布局 且不重新设置oneLabel的约束

-(void)setModel:(Model*)model {
  self.oneLabel.text = @"这里做一个测试数据的展示";      
 DLog(@"..self.oneLabel.frame==%@",NSStringFromCGRect(self.oneLabel.frame));
self.TwoImageView.frame = CGRectMake(CGRectGetMaxX(self.oneLabel.frame)+4,CGRectGetMinY(self.oneLabel.frame)+4,56,17);
DLog(@"..self.TwoImageView.frame==%@",NSStringFromCGRect(self.TwoImageView.frame));
打印出来数据会出现宽度和高度为0 的情况。导致self.TwoImageView.frame设置出来也有误差。

这样在滑动复用的时候就出现了 遮盖问题。

}
最后翻阅了一些资料 如何能够很好把一下几个点结合起来(懒加载布局Cell子控件,在layoutSubviews中写约束,Cell内部有动态且依赖的组件块,纯Masory动态布)
这几个点都结合起来的方法 还是没有翻阅到。
当然查询还是有收获的。
借鉴了一下文章:https://juejin.im/post/5a3238876fb9a0451c3a6af7,https://blog.csdn.net/MinggeQingchun/article/details/102677233

改造了下实现方法。还是正确处理这个问题了。
以下是改动点。

  1. 这个新增一个约束方法 添加控件之后做约束,不在-(void)layoutSubviews里面去做。
-(instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
    if (self =[super initWithStyle:style reuseIdentifier:reuseIdentifier]) {

        [self.contentView addSubview:self.oneLabel];
        [self.contentView addSubview:self.TwoImageView];
         [self masoryForSubViews];
    }
    return  self;
}

-(void)masoryForSubViews {
  //这里设置约束代码
[self.oneLabel mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.equalTo(self.contentView).offset(16);
        make.top.equalTo(self.contentView).offset(20);
        make.height.mas_equalTo(24);
    }];
//这里只对oneLabel做了约束 
}

2.改造赋值方法

-(void)setModel:(Model*)model {
  self.oneLabel.text = @"这里做一个测试数据的展示"; 

//这个方法使得self.oneLabel 约束完毕的frame不再为0
 [self layoutIfNeeded];
 DLog(@"..self.oneLabel.frame==%@",NSStringFromCGRect(self.oneLabel.frame));
//用frame给TwoImageView 设置frame
self.TwoImageView.frame = CGRectMake(CGRectGetMaxX(self.oneLabel.frame)+4,CGRectGetMinY(self.oneLabel.frame)+4,56,17);
DLog(@"..self.TwoImageView.frame==%@",NSStringFromCGRect(self.TwoImageView.frame));

}
这样的话 这个问题也可以正常展示。打印出来的frame和展示出来都是正确的。
问题是解决了,还是对懒加载布局Cell子控件、在layoutSubviews中写约束、Cell内部有动态且依赖的组件块、纯Masory动态布
、这几个条件同事存在情况下 如何处理比较有疑问。这里先记录下这个问题。如果有幸这篇文章能被哪位大神看到,还希望大神能给予指点。

你可能感兴趣的:(iOS_Masory布局踩坑)