UITableView row animation duration and completion

2019-01-04 05:49发布

Is there a way to either specify the duration for UITableView row animations, or to get a callback when the animation completes?

What I would like to do is flash the scroll indicators after the animation completes. Doing the flash before then doesn't do anything. So far the workaround I have is to delay half a second (that seems to be the default animation duration), i.e.:

[self.tableView insertRowsAtIndexPaths:newRows
                      withRowAnimation:UITableViewRowAnimationFade];
[self.tableView performSelector:@selector(flashScrollIndicators)
                     withObject:nil
                     afterDelay:0.5];

8条回答
The star\"
2楼-- · 2019-01-04 06:17

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.

查看更多
家丑人穷心不美
3楼-- · 2019-01-04 06:23

Shortening Brent's fine answer, for at least iOS 7 you can wrap this all tersely in a [UIView animateWithDuration:delay:options:animations:completion:] call:

[UIView animateWithDuration:10 delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
  [self.tableView beginUpdates];
  [self.tableView endUpdates];
} completion:^(BOOL finished) {
  // completion code
}];

though, I can't seem to override the default animation curve from anything other than EaseInOut.

查看更多
做个烂人
4楼-- · 2019-01-04 06:23

Override tableView -insertRowsAtIndexPaths: and implement the custom insertion/(or the deletion with its own method) animation you want. Didn't try it my self though.

查看更多
不美不萌又怎样
5楼-- · 2019-01-04 06:27

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()
查看更多
等我变得足够好
6楼-- · 2019-01-04 06:32

Here's a Swift version of karwag's answer

    CATransaction.begin()
    tableView.beginUpdates()
    CATransaction.setCompletionBlock { () -> Void in
        // your code here
    }
    tableView.insertRowsAtIndexPaths(indexArray, withRowAnimation: .Top)
    tableView.endUpdates()
    CATransaction.commit()
查看更多
我想做一个坏孩纸
7楼-- · 2019-01-04 06:35

You could try to wrap the insertRowsAtIndexPath in a

- (void)beginUpdates
- (void)endUpdates

transaction, then do the flash afterwards.

查看更多
登录 后发表回答