I have a tableview with buttons that can increase and decrease the contentView's height of individual cells. The individual cells have a lot of configurations that aren't persisted.(The end solution definitely includes persisting the data, but there are other issues that follow) I want to be able to click a button in any cell, have the cell expand pushing other cells down, and have all the cells keep their configured data.
If I just use reloadData, then I have to persist everything, and do a lot of unnecessary reprocessing when I am only editing one cell. Lastly, there isn't any free animation to expand or shrink.
This leads to table view updates and cell reloads which do come with animations and less overhead. I can just call UITableView.beginUpdates and UITableView.endUpdates. Or more ideally, I just call reloadRowsAtIndexPaths for the visible cells after the editing cell. In this case, this would animate the height change while keep my current cells data current. But this doesn't work.
Finally, here is the problem. UITableView.beginUpdates, UITableView.endUpdates, and reloadRowsAtIndexPaths cause the table view to scroll. That means if the cell you are trying to change the height of has an indexPath high enough, it will be dequeued and reused. All my configuration data is thrown out, and I have cells that aren't moving on the screen being completely recycled. (I found this out by setting a random background color on the cell during prepareForReuse.)
Now you are saying, duh this is simple just disable implicit animations, and force reset the tableview's contentOffset of the underlying scrollview like so:
UIView.setAnimationsEnabled(false)
let contentOffset = tableView.contentOffset
tableView.beginUpdates()
tableView.endUpdates()
tableView.setContentOffset(contentOffset, animated: false)
UIView.setAnimationsEnabled(true)
Well under the hood, the content offset change is fully processed, and my cells are still recycled. Is there anyway around this recycling?