美文网首页
iOS_Masory布局踩坑

iOS_Masory布局踩坑

作者: 爱笑的猫mi | 来源:发表于2020-03-25 11:27 被阅读0次

    一、源起

    最近在使用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/5a3238876fb9a0451c3a6af7https://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布局踩坑

          本文链接:https://www.haomeiwen.com/subject/prqtuhtx.html