在iOS开发中或多或少的都会碰到TableViewCell高度自适应,那么今天这篇文章就简单的介绍一下如何给tableViewCell自适应高度 #ViewController copy
@interface ViewController ()<UITableViewDelegate, UITableViewDataSource>{
UITableView *_tableView;
}
@property (nonatomic, strong) NSMutableArray *modelArr;
@property (nonatomic, assign) CGFloat rowHeight; //确定cell的高度
@end
@implementation ViewController
- (NSMutableArray *)modelArr{ //初始化model
if (!_modelArr) {
NSArray *arr = @[@"大概是因为最近发了一些关于唐诗的文章,有读者发来消息,说家里有孩子马上要上初中,希望我能够推荐书单,“学校的老师只是让不停地抄写,推荐的书她也不爱看,自己选书看。\"",@"但其实,我并不喜欢向人推荐书单。因为在我看来,阅读,其实是很私人化的事情。", @"我一直记得我以前写过我在读大学时看《约翰·克里斯多夫》的情景——我花了大半个学期,费尽心神,才将那本厚厚的书我读了三分之二。但后来,我还是无法坚持下去。那个时候的我,根本不知道那本书要说什么,书里写的内容,现在也毫无印象。",@"“那个变态,居然读《约翰·克里斯多夫》。”有室友说。", @"从此之后的很长时间,我几乎都不再看世界名著。即便看《约翰·克里斯多夫》的时候,我是中文系大二的学生,专业课成绩在班级里名列前茅。"];
_modelArr = [NSMutableArray arrayWithArray:arr];
}
return _modelArr;
}
复制代码
rowHeight
保存计算好的cell的高度,然后在delegate中给cell高度赋值
modelArr
在get方法中初始化模型数组,当使用时就去创建,减少内存开支 #ViewController copy
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor whiteColor];
[self createTableView]; //创建tableView
}
static NSString *cellId = @"cellId";
- (void)createTableView{
_tableView = [[UITableView alloc] initWithFrame:self.view.bounds];
_tableView.dataSource = self;
_tableView.delegate = self;
_tableView.estimatedRowHeight = 130; //估算cell高度
[self.view addSubview:_tableView];
[_tableView registerClass:[MyTableViewCell class] forCellReuseIdentifier:cellId];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return self.modelArr.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
MyTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellId];
cell.text = self.modelArr[indexPath.row]; //给cell赋值
self.rowHeight = cell.rowHeight; //返回cell高度
return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
return self.rowHeight;
}
复制代码
_tableView.estimatedRowHeight = 130;
如果你不加这句话的话TableView也是正常显示,但是当你在返回cell和cell高度的方法中打个断点你会发现在还没返回cell的时候它就在一直调用这个方法
3*self.modelArr.count 次 为什么会有这么多次暂时留一个小尾巴,以后再仔细研究
当调用完这个方法之后再走的是返回cell的方法,然后再走返回高度的方法 所以当你的cell高度差距不确定的时候,最好给cell估算一个大概高度以便提高运行效率
MyTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellId]; cell.text = self.modelArr[indexPath.row]; //给cell赋值 self.rowHeight = cell.rowHeight; //返回cell高度
这里一定是先给cell填充内容然后再获取cell高度,一定要在控制器里保存一下rowHeight 如果你这样写
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
return ((MyTableViewCell *)[tableView cellForRowAtIndexPath:indexPath]).rowHeight;
}
复制代码
你会发现所有的cell都挤在了一起,很无语
这里也是一个遗留问题的小尾巴
#MyTableViewCell copy
@interface MyTableViewCell : UITableViewCell
@property (nonatomic, copy) NSString *text;
@property (nonatomic, strong) UIImageView *imageV;
@property (nonatomic, strong) UILabel *label;
@property (nonatomic, assign) CGFloat rowHeight;
@end
@implementation MyTableViewCell
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier{
if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) {
_imageV = [[UIImageView alloc] init];
_imageV.image = [UIImage imageNamed:@"icon_add_img"]; //气泡图片
[self.contentView addSubview:_imageV];
_label = [[UILabel alloc] init];
_label.numberOfLines = 0; //设置label行数为最大
[_imageV addSubview:_label];
}
return self;
}
- (void)setText:(NSString *)text{
_text = text;
_label.text = text;
_label.font = [UIFont systemFontOfSize:14.0];
//计算label高度
CGRect rect = [text boundingRectWithSize:CGSizeMake(self.frame.size.width - 160, 99999) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName : [UIFont systemFontOfSize:14.0]} context:nil];
_label.frame = CGRectMake(80, 10, rect.size.width, rect.size.height);
_imageV.frame = CGRectMake(30, 10, rect.size.width + 160, rect.size.height + 80);
[_imageV.image stretchableImageWithLeftCapWidth:150 topCapHeight:0]; //拉伸image
_rowHeight = CGRectGetMaxY(_imageV.frame) + 20; //获取cell高度
}
@end
复制代码
CGRect rect = [text boundingRectWithSize:CGSizeMake(self.frame.size.width - 160, 99999) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName : [UIFont systemFontOfSize:14.0]} context:nil];
通过这个方法来计算label的高度,然后返回给cell的rowHeight 把我给的代码复制粘贴运行一下是不是可以了 或许你觉得label不是从x=0的位置开始的,是因为在label的frame位置设置的x=80并且把label加在了imageVIew上了,自己改一下就行了,或者你拿一个气泡图片放上面试试效果也不错
运行一下代码试试
其实正确的图片是最后这个,但是第一张图的cell右侧为什么会出现一部分空白地方呢,这也是一个问题(猜想:空白位置是cell删除按钮的宽度)
一篇文章下来出现了很多问题,现在总结一下怎么解决cell高度自适应的问题 1.在cell里面定义一个rowHeight,当传入数据的时候给rowHeight赋值 2.计算label高度可以用到boundingRectWithSize这个方法 3.在创建TableView的时候最好给rowHeight一个估值,以便提高运行效率 4.在控制器中定义一个rowHeight以便保存赋值之后的cell高度 5.聊天气泡图片拉伸方法stretchableImageWithLeftCapWidth
存在的问题 ##为什么返回cell高度的方法会走了3遍的modelArr.count ##为什么不能通过cell直接获取cell高度
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
return ((MyTableViewCell *)[tableView cellForRowAtIndexPath:indexPath]).rowHeight;
}
复制代码
##为什么cell右侧会空余出删除按钮的宽度 解决方案:这个确实是历史遗留问题,在layoutSubviews里面更新一下控件的frame就可以了
希望有知道解决方法的大神能给予指点,多谢多谢