具有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
- 运行该项目。
- 滚动,直到细胞10在视野中。
- 等待长达5秒钟的单元重新加载(它变成紫色)。
- 向上滑动。
值得注意的是,如果单元格在重新加载时不在视图中,则不会发生这种情况。 如果它高于或低于当前的滚动点,则一切按预期工作。
这种行为似乎是一个错误,如果没有其他原因,而不是在iOS 9上不能重现。我相信这并不是什么安慰。
这个问题主要是由于有一个不准确的估计,就像@NickCatib所说。 你可以在iOS 8上做的最好的是改善估计。 许多人推荐的技术是在willDisplayCell
caching高度,并在随后调用estimatedRowHeightAtIndexPath
使用它们。
您可以通过不做任何事情来让UITableView
放弃其caching,例如通过直接使用cellForRowAtIndexPath
修改单元格中的内容,而不是在屏幕上使用重新加载来缓解行为。 但是,如果实际上需要更改单元格的高度,这将无济于事。
我不敢说这个bug不能在表格视图中被修复,因为你不能控制布局。 通过在失效期间更改contentOffsetAdjustment
,该错误可以更容易地在UICollectionViewFlowLayout
的子类中UICollectionViewFlowLayout
,尽pipe这可能不是非常容易。
我也有这个问题,并使用了我现在找不到的SO的解决scheme。 如果我这样做,我会添加链接。 这是解决scheme:
问题是表视图没有正确的行高估计。 为了解决这个问题,最初在willDisplayCell
caching高度,下一次使用该高度。
码
在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。 如果我可以谢谢