在开发中也遇到了UITableView刷新跳动的问题,搜索一下解决方案,但是基本都是如下的做法
_tableView.estimatedRowHeight = 0;
_tableView.estimatedSectionHeaderHeight = 0;
_tableView.estimatedSectionFooterHeight = 0;
这一方案实际上是禁用了自动计算,从而使UITableView刷新不再跳动。
但是这是一个带有误伤的方案。estimatedRowHeight = 0 同时禁用了方便的AutomaticDimension。
对于手动计算高度的方式,这样是没什么问题的,但是如果用到了AutomaticDimension,怎么办呢。
一个简单有效的方案,就是缓存高度。
- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSNumber *heightNumber = [self.cellHeightDict objectForKey:indexPath];
CGFloat height = 50;
if(heightNumber)
{
height = heightNumber.floatValue;
}
return height;
}
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
CGFloat cellHeight = cell.frame.size.height;
[self.cellHeightDict setObject:@(cellHeight) forKey:indexPath];
}
方案的本质是提供准确的estimatedRowHeight使得UITableView的contentSize计算准确,从而不会产生所谓的跳动现象。
这其实也揭示了一点,estimatedRowHeight其实并非应该随意设置,而是应该尽可能的准确,日常使用可能会忽略这一点,所以会有许多奇怪的bug出现,这些都是没有准确使用的结果。(当然,会有一些准确使用也有的奇怪问题)
当然,如果Header和Footer也使用estimated的话,就在willDisplayHeaderView 和 willDisplayFooterView 把实际高度也存储起来就行了。不需要的话就把estimated设置为0。