UITableView row animation duration and completion callback
Just came across this. Here's how to do it:
Objective-C
[CATransaction begin];[tableView beginUpdates];[CATransaction setCompletionBlock: ^{ // Code to be executed upon completion}];[tableView insertRowsAtIndexPaths: indexPaths withRowAnimation: UITableViewRowAnimationAutomatic];[tableView endUpdates];[CATransaction commit];
Swift
CATransaction.begin()tableView.beginUpdates()CATransaction.setCompletionBlock { // Code to be executed upon completion}tableView.insertRowsAtIndexPaths(indexArray, withRowAnimation: .Top)tableView.endUpdates()CATransaction.commit()
Expanding on karwag's fine answer, note that on iOS 7, surrounding the CATransaction with a UIView Animation offers control of the table animation duration.
[UIView beginAnimations:@"myAnimationId" context:nil];[UIView setAnimationDuration:10.0]; // Set duration here[CATransaction begin];[CATransaction setCompletionBlock:^{ NSLog(@"Complete!");}];[myTable beginUpdates];// my table changes[myTable endUpdates];[CATransaction commit];[UIView commitAnimations];
The UIView animation's duration has no effect on iOS 6. Perhaps iOS 7 table animations are implemented differently, at the UIView level.
That's one hell of a useful trick!I wrote a UITableView extension to avoid writing CATransaction stuff all the time.
import UIKitextension UITableView { /// Perform a series of method calls that insert, delete, or select rows and sections of the table view. /// This is equivalent to a beginUpdates() / endUpdates() sequence, /// with a completion closure when the animation is finished. /// Parameter update: the update operation to perform on the tableView. /// Parameter completion: the completion closure to be executed when the animation is completed. func performUpdate(_ update: ()->Void, completion: (()->Void)?) { CATransaction.begin() CATransaction.setCompletionBlock(completion) // Table View update on row / section beginUpdates() update() endUpdates() CATransaction.commit() }}
This is used like so:
// Insert in the tableView the section we just added in sectionsself.tableView.performUpdate({ self.tableView.insertSections([newSectionIndex], with: UITableViewRowAnimation.top)}, completion: { // Scroll to next section let nextSectionIndexPath = IndexPath(row: 0, section: newSectionIndex) self.tableView.scrollToRow(at: nextSectionIndexPath, at: .top, animated: true)})