具有dynamic单元高度的UITableView在重新加载单元格后向上滚动时跳转

我有一个表格视图,每个单元格都有自己的高度,因此不适合使用rowHeight 。 相反,现在我使用let indexSet = NSIndexSet(index: 10)self.tableView.estimatedRowHeight = 75 。 这意味着它调用单元格上的sizeThatFits函数来确定它的高度。 这一切运作良好。

问题是当你重新加载屏幕上的单元格。 例如向下滚动显示单元10,然后重新加载单元10,工作正常。 但是当你开始向上滚动时,通过已经看过的单元格,它将恢复到每个单元格的估计的sizeThatFits ,完全忽略sizeThatFits ,所以在你滚动的时候会跳转。 我不可能给出一个准确或“足够好”的估计的高度,这样这个跳跃就不会显而易见,因为我的细胞能够显示一行文本或一个完整的图像 – 尺寸。

我已经在这里显示了这个效果:

https://vid.me/edgW

我做了很多不同的尝试,使用了一个混合的heightForRowAtIndexPath,estimatedHeightForRowAtIndexPath ..等。我已经尝试了各种build议StackOverflow。 似乎没有任何工作。

我附上了一个非常简单的示例项目,您可以在其中自行尝试:

https://www.dropbox.com/s/8f1rvkx9k23q6c1/tableviewtest.zip?dl=0

  1. 运行该项目。
  2. 滚动,直到细胞10在视野中。
  3. 等待长达5秒钟的单元重新加载(它变成紫色)。
  4. 向上滑动。

值得注意的是,如果单元格在重新加载时不在视图中,则不会发生这种情况。 如果它高于低于当前的滚动点,则一切按预期工作。

这种行为似乎是一个错误,如果没有其他原因,而不是在iOS 9上不能重现。我相信这并不是什么安慰。

这个问题主要是由于有一个不准确的估计,就像@NickCatib所说。 你可以在iOS 8上做的最好的是改善估计。 许多人推荐的技术是在willDisplayCellcaching高度,并在随后调用estimatedRowHeightAtIndexPath使用它们。

您可以通过不做任何事情来让UITableView放弃其caching,例如通过直接使用cellForRowAtIndexPath修改单元格中的内容,而不是在屏幕上使用重新加载来缓解行为。 但是,如果实际上需要更改单元格的高度,这将无济于事。

我不敢说这个bug不能在表格视图中被修复,因为你不能控制布局。 通过在失效期间更改contentOffsetAdjustment ,该错误可以更容易地在UICollectionViewFlowLayout的子类中UICollectionViewFlowLayout ,尽pipe这可能不是非常容易。

我也有这个问题,并使用了我现在找不到的SO的解决scheme。 如果我这样做,我会添加链接。 这是解决scheme:

问题是表视图没有正确的行高估计。 为了解决这个问题,最初在willDisplayCellcaching高度,下一次使用该高度。

在viewDidLoad中:

 heightAtIndexPath = [NSMutableDictionary new]; - (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath { NSNumber *height = @(cell.frame.size.height); [heightAtIndexPath setObject:height forKey:indexPath]; } - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ return UITableViewAutomaticDimension; } - (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath{ if([heightAtIndexPath objectForKey:indexPath]) { return [[heightAtIndexPath objectForKey:indexPath] floatValue]; } else { return UITableViewAutomaticDimension; } } 

呃…这是一个很难处理的问题。

让我们来看看Facebook。 他们在他们的时间表上也有这个问题,他们最终以某种networking观点来做。

我有一个类似的问题,某种时间表,使用自动行高,并有这个问题。 首先解决的办法是将estimatedHeight高度设置得尽可能接近平均细胞高度。 这很难处理,因为你可能有文字(高度50)或图像+文字(高度1500)。 接下来要做的就是实现estimatedHeight forIndexPath ,它基本上为不同的索引path返回不同的估计高度。

之后,还有很多其他的解决scheme,但是这个解决scheme尽可能地接近可变高度(巨大差异)。

我面临着同样的问题,我的表工作正常,直到tableview重新加载。 所以我find了一个解决scheme,只使用rowHeight不估计的高度。 另外如果你有不同的身高。 所以请提供完整的代码,我将提供一个解决scheme。 我有一个像Instagram页面的单元格。 我正在通过计算高度在高度运行方式,工作正常。 但估计高度在这种情况下不能正常工作。 如果您使用下面的代码,它工作正常。 请尝试。

 self.tableView.rowHeight = 75 //it will be your dynamic height //self.tableView.estimatedRowHeight = 75 

如果你混淆为每个单元格计算行的高度,只需发布​​样本我将提供解决scheme。 如果我可以谢谢