重新加载单元格高度变化的单元格时,UITableView 滚动到顶部
Posted
技术标签:
【中文标题】重新加载单元格高度变化的单元格时,UITableView 滚动到顶部【英文标题】:UITableView scrolls to top when reloading cells with changing cell heights 【发布时间】:2015-09-02 20:47:22 【问题描述】:我有一个表格视图,它在加载图像时包含一个占位符。加载图像时,我调用reloadRowsAtIndexPaths:withRowAnimation:
。此时,单元格会根据图像的大小改变高度。发生这种情况时,我希望表格视图的内容偏移保持在原位,并让下面的单元格被进一步向下推,正如您可能想象的那样。
我得到的效果是滚动视图滚动回顶部。我不确定为什么会这样,而且我似乎无法阻止它。将beginUpdates()
放在reloadRows
行之前和endUpdates()
之后没有效果。
我正在使用estimatedRowHeight
,因为我的表格视图可能有数百行不同高度的行。我也在执行tableView:heightForRowAtIndexPath:
。
编辑:我已经建立了一个演示项目来对此进行测试,并且不可否认我无法让演示项目重现这种效果。我会继续努力的。
【问题讨论】:
您能否发布用于获取 tableview 的内容偏移量并设置您希望 tableview 的焦点保持在哪里的代码? 【参考方案1】:这是estimatedRowHeight 的问题。
estimatedRowHeight 与实际高度的差异越大,重新加载时表格可能会跳得越多,尤其是向下滚动的地方越多。这是因为表格的估计大小与其实际大小完全不同,迫使表格调整其内容大小和偏移量。
最简单的解决方法是使用非常准确的估算值。如果每行的高度变化很大,请确定一行的中间高度,并将其用作估计值。
【讨论】:
在我的测试中,我尝试了一个非常小的估计值和一个非常大的估计值,但都没有产生不必要的滚动效果。 这是一个很好的答案。谢谢你。估计高度不应该是随机数,而是接近您认为的高度。 我使用了估计大小的调整单元格(我猜哪种违背了 UITableViewAutomaticDimension 的目的?)。它为我解决了这个问题。这是因为我的单元格的大小变化很大(根据用户在嵌入的 UITextViews 中键入的内容)【参考方案2】:始终在主线程上更新 UI。所以只需放置
[self.tableView reloadData];
在主线程内:
dispatch_async(dispatch_get_main_queue(), ^
//UI Updating code here.
[self.tableView reloadData];
);
【讨论】:
在主线程中执行重新加载如何影响滚动到顶部?【参考方案3】:我遇到了同样的问题并通过这种方式决定:在加载时保存单元格的高度并在tableView:estimatedHeightForRowAtIndexPath
中给出确切的值:
// declare cellHeightsDictionary
NSMutableDictionary *cellHeightsDictionary;
// 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;
【讨论】:
就我而言,我在超类中有self.tableView.estimatedRowHeight = 44;
。在当前类中将其设置为零,我有固定的行高解决了这个问题。【参考方案4】:
我看到了这一点,对我有用的解决方法是选择可能行中最小的估计行高。当意外滚动发生时,它最初被设置为最大可能的行高。我只是使用单个 tableView.estimatedRowHeight
属性,而不是委托方法。
【讨论】:
以上是关于重新加载单元格高度变化的单元格时,UITableView 滚动到顶部的主要内容,如果未能解决你的问题,请参考以下文章
如何在使用tableViews自定义单元格时在运行时更改表视图单元格高度?
动画 UICollectionView 单元格大小更改和重新定位周围的单元格
UITableView rowHeight UITableViewAutomaticDimension 首次加载后单元格高度错误