在开发中, 经常碰到cell需要动态调节的情况, 例如聊天页面等, 但是IOS不像Android一样有wrap(wrap就是根据内容的大小,自动调节), 所以在IOS端处理cell高度就蛋疼了
下面介绍三种方法动态调节
方法1-手动计算
在设置cell的model的时候, 调节动态计算cell的高度, 然后再去设置cell的高度
如果你的cell内容比较简单, 就一个label或者cell文字可能多行的label在cell最末端, 那么只需要计算这个label的size, 然后赋值给cell即可:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *ID = @"Cell";
CGFloat padding = 20;
CJDemoTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
if (!cell) {
cell = [[[NSBundle mainBundle] loadNibNamed:@"CJDemoTableViewCell" owner:self options:nil] lastObject];
}
CJDemoModel *model = self.models[indexPath.row];
cell.model = model;
//此处是个计算size的string分类,后面会附上
cell.lastLabel.size = [model.testTest sizeWithFont:[UIFont systemFontOfSize:17] maxW:contentLW];
cell.height = CGRectGetMaxY(cell.lastLabel.frame) + padding;
return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell = [self tableView:tableView cellForRowAtIndexPath:indexPath];
return cell.height;
}
如果cell多个label可能多行, 那么就需要计算多个label的size, 最好在cell的setModel方法里面进行
//cell setModel方法
- (void)setModel:(CJDemoModel *)model{
_model = model;
CGFloat padding = 5;
self.nameL.text = model.name;
CGSize nameSize = [self.nameL.text sizeWithFont:[UIFont systemFontOfSize:17]];
nameSize.frame = CGRectMake(0,0,nameSize.width,nameSize.heigth);
self.scoreL.text = model.score;
CGSize scoreSize = [self.scoreL.text sizeWithFont:[UIFont systemFontOfSize:17]];
scoreL.frame = CGRectMake(0,CGRectGetMaxY(self.nameL.frame),scoreSize.width,scoreSize.heigth);
self.jobL.text = model.job;
CGSize jobSize = [self.jobL.text sizeWithFont:[UIFont systemFontOfSize:17]];
self.jobL.frame = CGRectMake(0,CGRectGetMaxY(self.scoreL.frame),jobSize.width,jobSize.height);
self.cellHeight = CGRectGetMaxY(self.jobL.frame) + padding;
}
//然后在设置cell的高度(controller)
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell = [self tableView:tableView cellForRowAtIndexPath:indexPath];
return cell.cellHeight;
}
方法2-FDTemplateLayoutCell
借助框架UITableView-FDTemplateLayoutCell
在- (CGFloat)tableView:(UITableView
)tableView heightForRowAtIndexPath:(NSIndexPath
)indexPath重新设置下model即可
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
return = [tableView fd_heightForCellWithIdentifier:ID configuration:^(CJDemoTableViewCell *cell) {
CJDemoModel *model = self.models[indexPath.row];
cell.model = model;
}];
}
}
github:
FDTemplateLayoutCell
如果使用时height返回不正确,请看
http://blog.csdn.net/corey_jia/article/details/49232779
方法三-IOS8特性
IOS8中, 提供了动态调节cell高度的方法, 通过XIB添加约束即可, 如果你的应用要适配IOS7及以下, 那么可以参考前两种方法
- 设置tableView的估算Cell高度&rowHeight值为自动计算模式
- (void)viewDidLoad {
[super viewDidLoad];
self.tableView.estimatedRowHeight = 100; // 随便设个不那么离谱的值
self.tableView.rowHeight = UITableViewAutomaticDimension;
}
-
设置约束, 最下面的view要上下左右都设置约束,不然无法计算正确高度
注意:
– 不能实现heightForRow代理方法!!!
本文用到的String_category
- (CGSize)sizeWithFont:(UIFont *)font maxW:(CGFloat)maxW
{
NSMutableDictionary *attrs = [NSMutableDictionary dictionary];
attrs[NSFontAttributeName] = font;
CGSize maxSize = CGSizeMake(maxW, MAXFLOAT);
return [self boundingRectWithSize:maxSize options:NSStringDrawingUsesLineFragmentOrigin attributes:attrs context:nil].size;
}
- (CGSize)sizeWithFont:(UIFont *)font
{
return [self sizeWithFont:font maxW:MAXFLOAT];
}