I have a UITableView
which under goes a batch update when the state of app changes. The change can effect a number of rows/sections or only one section (but 1 or more rows).
I've noticed that when under going a single section update (which may effect a number of rows in the section), the section headers for the other sections "bounce" or are "moved" from their previous position and then animated back into place.
A picture paints a thousand words...
These sections are not part of the batch update.
The UITableView
/Controller
is setup through a story board targeting iOS 11. The UITableView
is making use of the "Estimated" row and section heights and the cells are laid out using auto layout.
The UITableViewController
makes use of a larger data model which managers the state and state change operations. The API ensures that the required updates are calculated based on the required state of the model (i.e. deletes and updates relate to the "previous" state, inserts related to the "new" state)
The last step is to apply the calculated changes to the table view through a batch update process...
tableView.beginUpdates()
// Calculate the rows/sections which need to be changed
if let ops = operation.sections[.delete], ops.count > 0 {
tableView.deleteSections(ops, with: deleteSectionAnimation)
}
if let ops = operation.sections[.update], ops.count > 0 {
tableView.reloadSections(ops, with: reloadSectionAnimation)
}
if let ops = operation.sections[.insert], ops.count > 0 {
tableView.insertSections(ops, with: insertSectionAnimation)
}
if let ops = operation.rows[.delete], ops.count > 0 {
tableView.deleteRows(at: ops, with: deleteRowAnimation)
}
if let ops = operation.rows[.update], ops.count > 0 {
tableView.reloadRows(at: ops, with: reloadRowAnimation)
}
if let ops = operation.rows[.insert], ops.count > 0 {
tableView.insertRows(at: ops, with: insertRowAnimation)
}
tableView.endUpdates()
tableView.reloadData()
tableView.layoutIfNeeded()
The row and section animation properties (i.e. deleteSectionAnimation
) are set to automatic
. I've tried setting the section animations to none
without any differences
I've tried removing the reloadData
and layoutIfNeeded
in varying combinations and while they create other issues, they don't seem to come close to resolving this issue
One thing I've noticed, is this only seems to occur when the updates occurring to the UITableView
are been done off screen
I've spend some time trying to find a solution to the issue (like not calling reloadData
) but can't find something which works.
Is there some other property, function I should look at or is the order in which the updates are been executed wrong?
Notes
- This is a "static" table, setup through storyboards
- The rows and sections are been added/removed during state changes, which seems to trigger issues/changes in the scroll view
- While disabling animation (with
UIView.setAnimationsEnabled
) does seem to fix the issue, it's an undesirable solution, as it removes the animations for all updates (on or off screen) - The issue only occurs when the scroll view is NOT at the top of the view, updates/animations occurring when the table view is scrolled all the way to the top have no issues
- I've tried using
indexPathsForVisibleRows
to determine if the updates are occurring on or off the screen, and disable the animation usingUIView.setAnimationsEnabled
but it doesn't solve the issue if the update occurs on the screen while the table view is not scrolled to the top of the scroll view