一尘不染

具有动态单元格高度的UITableView的reloadData()导致跳跃式滚动

swift

我觉得这可能是一个常见的问题,并且想知道是否有任何通用的解决方案。

基本上,我的UITableView具有每个单元格的动态单元格高度。如果我不在UITableView和I的顶部,则tableView.reloadData()向上滚动变得跳动。

我相信这是由于以下事实:当我向上滚动时重新加载数据时,UITableView正在重新计算每个可见的单元格的高度。如何缓解这种情况,或者如何仅将数据从某个IndexPath重新加载到UITableView的末尾?

此外,当我确实设法一直滚动到顶部时,我可以先向下再向上滚动,毫无问题。这很可能是因为已经计算了UITableViewCell的高度。


阅读 318

收藏
2020-07-07

共1个答案

一尘不染

为防止跳跃,应在加载单元格时保留它们的高度,并在tableView:estimatedHeightForRowAtIndexPath以下位置给出确切值:

迅速:

var cellHeights = [IndexPath: CGFloat]()

func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
    cellHeights[indexPath] = cell.frame.size.height
}

func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
    return cellHeights[indexPath] ?? UITableView.automaticDimension
}

目标C:

// declare cellHeightsDictionary
NSMutableDictionary *cellHeightsDictionary = @{}.mutableCopy;

// declare table dynamic row height and create correct constraints in cells
tableView.rowHeight = UITableViewAutomaticDimension;

// save height
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
    [cellHeightsDictionary setObject:@(cell.frame.size.height) forKey:indexPath];
}

// give exact height value
- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath {
    NSNumber *height = [cellHeightsDictionary objectForKey:indexPath];
    if (height) return height.doubleValue;
    return UITableViewAutomaticDimension;
}
2020-07-07