重新加载单元格后向上滚动时,动态单元格高度跳跃的UITableView [英] UITableView with dynamic cell heights jumping when scrolling up after reloading cell

查看:101
本文介绍了重新加载单元格后向上滚动时,动态单元格高度跳跃的UITableView的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a table view with the potential for each cell to have its own height, thus isn't suitable to use rowHeight. Instead, right now I'm using let indexSet = NSIndexSet(index: 10), and self.tableView.estimatedRowHeight = 75. This means that it calls the sizeThatFits function on the cell, to determine its' height. This all works well.

当你重新加载屏幕上的一个单元格时,问题就出现了。例如,向下滚动以显示单元格10,然后重新加载单元格10,工作正常。但是当你开始向上滚动,经过你已经看过的单元格时,它会恢复到每个单元格的estimatedRowHeight,完全无视 sizeThatFits ,所以当你跳过时滚动。我不可能给出一个准确的或足够好的估计值,因此这种跳跃不会引人注意,因为我的细胞能够显示一行文字或一个完整的图像 - 这是一个很大的区别。大小。

The problem is then when you reload a cell that's onscreen. Scrolling down to show cell 10, for example, then reloading cell 10, works fine. But when you begin to scroll back up, past the cells you've already seen, it reverts to the estimatedRowHeight for each cell, completely disregarding sizeThatFits, and so jumps around as you scroll. It'd be impossible for me to give an accurate or 'good enough' estimatedRowHeight so that this jumping wouldn't be noticeable, as my cells will be able to display either a line of text, or a full image - a big difference in size.

我在这里看到了这种效果:

I've shown this effect here:

https://vid.me/edgW

我使用heightForRowAtIndexPath的混合物做了很多不同的尝试, estimatedHeightForRowAtIndexPath ..等等。我在StackOverflow上尝试了各种建议。似乎没什么用。

I've made many different attempts at this, using a mixture of heightForRowAtIndexPath, estimatedHeightForRowAtIndexPath.. etc.. I've tried various pieces of advice on StackOverflow. Nothing seems to work.

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

I've attached a very simple sample project, where you can try it for yourself:

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


  1. 运行项目。

  2. 滚动直到查看单元格10 。

  3. 等待最多5秒钟让细胞重新加载(它变成紫色)。

  4. 向上滚动。

  1. Run the project.
  2. Scroll until cell 10 is in view.
  3. Wait up to 5 seconds for the cell to reload (it becomes purple).
  4. Scroll up.

值得注意的是 - 如果单元格在重新加载时不在视图中,则会发生 not 。如果它位于当前滚动点下方的之上,则一切都按预期工作。

Worth noting - this does not happen if the cell is not in view when it's reloaded. If it's either above or below the current scroll point, everything works as expected.

推荐答案

此行为似乎是一个错误,如果没有其他原因,它在iOS 9上不再可再现。我确信这不是很多安慰。

This behavior appears to be a bug, if for no other reason than it's no longer reproducible on iOS 9. I'm sure that's not much consolation.

问题主要来自于一个不准确的估计,像@NickCatib说。您在iOS 8上可以做的最好的事情就是改进估算。许多人建议的技术是在 willDisplayCell 中缓存高度,并在后续调用 estimatedRowHeightAtIndexPath 时使用它们。

The issue primarily derives from having an inaccurate estimate, like @NickCatib said. The best you can do on iOS 8 is to improve the estimation. A technique many have recommended is to cache heights in willDisplayCell and use them on subsequent calls to estimatedRowHeightAtIndexPath.

您可以通过不执行任何操作来缓解行为,以放弃其缓存,例如通过修改内容来缓存其内容一个单元格直接使用 cellForRowAtIndexPath 而不是使用重新加载(如果它在屏幕上)。但是,如果您确实需要更改单元格的高度,那将无济于事。

You might be able to mitigate the behavior by not doing anything to get UITableView to discard its caches, like by modifying the content in a cell directly using cellForRowAtIndexPath rather than using reloading if it's onscreen. However, that won't help if you actually need to change the height of the cell.

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

I'm afraid to say the bug can't be easily be fixed within a table view, as you don't have control over the layout. The bug can be more easily worked around in a subclass UICollectionViewFlowLayout by changing the contentOffsetAdjustment during invalidation, although that might not be terribly easy.

这篇关于重新加载单元格后向上滚动时,动态单元格高度跳跃的UITableView的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆