原理:TableView繼承自UIScrollView瞒渠。所以先要求要有contentView的尺寸唠亚,然后具體顯示某個(gè)cell的時(shí)候再計(jì)算cell的高度。所以每次cell顯示的時(shí)候都要重新計(jì)算他的高度皱炉。
二種方案:
一:計(jì)算具體cell真實(shí)高度兑巾。
原理:若有row height或者- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;通過他們直接計(jì)算出TableView的contentView高度。當(dāng)顯示某個(gè)cell的時(shí)候直接調(diào)用他們顯示饰剥。優(yōu)先級(jí)最高殊霞。
方法可以才用手動(dòng)計(jì)算cell的高度,緩存cell的高度避免每次計(jì)算汰蓉。每次顯示的時(shí)候先看緩存里面有cell的高度沒有绷蹲,沒有就計(jì)算,計(jì)算了放入緩存顾孽。cell的高度最好放入Model模型祝钢。
二:采用預(yù)估高度,采用約束計(jì)算cell真實(shí)高度若厚。
原理:若無row height或者- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;通過estimatedRowHeight或者- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath NS_AVAILABLE_IOS(7_0);計(jì)算出估算的contentView的高度拦英。iOS8之后tableView的row height默認(rèn)設(shè)置為UITableViewAutomaticDimension, 這個(gè)時(shí)候具體的某個(gè)cell的高度由cell的布局自動(dòng)計(jì)算高度测秸。
預(yù)估高度越接近真實(shí)高度越好疤估,若差別過大會(huì)出現(xiàn)tableView閃爍跳躍。若cell的高度變化范圍過大且不確定霎冯,可用代理設(shè)置預(yù)估高度铃拇。第一次將要顯示的時(shí)候
-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath{
NSInteger height = cell.height;
[self.cellHeightDic setObject:@(height) forKey:indexPath];
}
可以得到真實(shí)高度,然后把高度放入緩存預(yù)估高度數(shù)組肃晚。取預(yù)估高度的時(shí)候先看有沒有緩存高度有就用緩存高度锚贱,沒有就用平均高度仔戈。這里由于后面滑動(dòng)的時(shí)候數(shù)組里面都已經(jīng)有了預(yù)估高度且預(yù)估高度就是真實(shí)高度关串,所以完成不會(huì)出現(xiàn)閃爍跳躍現(xiàn)象且真實(shí)高度就是預(yù)估高度,所以從 預(yù)估—>真實(shí) 這一過程就可以忽略影響监徘,達(dá)到類似高度緩存的效果晋修。
-(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,即每個(gè)子視圖上下左右都要有約束凰盔,且可以把高度累加墓卦,若有大小不固定的圖片最好把圖片的尺寸放入到url里面。若有webView户敬,有待學(xué)習(xí)落剪。
當(dāng)滑動(dòng)到某個(gè)cell的時(shí)候每次都要計(jì)算cell的高度睁本,這比較費(fèi)時(shí)間可以采第三方UITableView+FDTemplateLayoutCell緩存cell的高度。注意cell中的label先設(shè)定換行寬度忠怖,否則要奔潰在高度緩存呢堰。 這個(gè)第三方好像在iOS10效果不明顯,且有卡頓現(xiàn)象樣凡泣,所以除非系統(tǒng)非惩魈郏卡頓才嘗試用該第三方。
- (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需要計(jì)算高度鞋拟,某些高度固定死了骂维。采用:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.row == 3) {
return 20;//固定死
}else{
return UITableViewAutomaticDimension;//采用約束計(jì)算的。
}
}