一、源起
最近在使用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
改造了下实现方法。还是正确处理这个问题了。
以下是改动点。
- 这个新增一个约束方法 添加控件之后做约束,不在-(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动态布
、这几个条件同事存在情况下 如何处理比较有疑问。这里先记录下这个问题。如果有幸这篇文章能被哪位大神看到,还希望大神能给予指点。
网友评论