UITableView row animation duration and completion callback UITableView row animation duration and completion callback ios ios

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)})