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.
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
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
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.
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.
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
.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With