原理:TableView继承自UIScrollView。所以先要求要有contentView的尺寸,然后具体显示某个cell的时候再计算cell的高度。所以每次cell显示的时候都要重新计算他的高度。
二种方案:
一:计算具体cell真实高度。
原理:若有row height或者- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;通过他们直接计算出TableView的contentView高度。当显示某个cell的时候直接调用他们显示。优先级最高。
方法可以才用手动计算cell的高度,缓存cell的高度避免每次计算。每次显示的时候先看缓存里面有cell的高度没有,没有就计算,计算了放入缓存。cell的高度最好放入Model模型。
二:采用预估高度,采用约束计算cell真实高度。
原理:若无row height或者- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;通过estimatedRowHeight或者- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath NS_AVAILABLE_IOS(7_0);计算出估算的contentView的高度。iOS8之后tableView的row height默认设置为UITableViewAutomaticDimension, 这个时候具体的某个cell的高度由cell的布局自动计算高度。
预估高度越接近真实高度越好,若差别过大会出现tableView闪烁跳跃。若cell的高度变化范围过大且不确定,可用代理设置预估高度。第一次将要显示的时候
-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath{
NSInteger height = cell.height;
[self.cellHeightDic setObject:@(height) forKey:indexPath];
}
可以得到真实高度,然后把高度放入缓存预估高度数组。取预估高度的时候先看有没有缓存高度有就用缓存高度,没有就用平均高度。这里由于后面滑动的时候数组里面都已经有了预估高度且预估高度就是真实高度,所以完成不会出现闪烁跳跃现象且真实高度就是预估高度,所以从 预估—>真实 这一过程就可以忽略影响,达到类似高度缓存的效果。
-(CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSNumber *height = [self.cellHeightDic objectForKey:indexPath];
if(height)
{
return height.floatValue;
}
else
{
return 100;
}
}
cell的布局要求:cell的contentView的子视图支持起contentView,即每个子视图上下左右都要有约束,且可以把高度累加,若有大小不固定的图片最好把图片的尺寸放入到url里面。若有webView,有待学习。
当滑动到某个cell的时候每次都要计算cell的高度,这比较费时间可以采第三方UITableView+FDTemplateLayoutCell缓存cell的高度。注意cell中的label先设定换行宽度,否则要奔溃在高度缓存。 这个第三方好像在iOS10效果不明显,且有卡顿现象样,所以除非系统非常卡顿才尝试用该第三方。
- (void)awakeFromNib {
[super awakeFromNib];
// Initialization code
self.userName.preferredMaxLayoutWidth = [UIScreen mainScreen].bounds.size.width - 66;
self.descLabel.preferredMaxLayoutWidth = [UIScreen mainScreen].bounds.size.width - 20;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return [tableView fd_heightForCellWithIdentifier:identify cacheByIndexPath:indexPath configuration:^(MKJTableViewCell *cell)
{
[self configCell:cell indexpath:indexPath];
}];
}
- 若只有某些cell需要计算高度,某些高度固定死了。采用:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.row == 3) {
return 20;//固定死
}else{
return UITableViewAutomaticDimension;//采用约束计算的。
}
}