cnotethegr8 cnotethegr8 - 11 months ago 441
Objective-C Question

UITableViewCell animate height issue in iOS 10


will animate it's height when recognizing a tap. In iOS 9 and below this animation is smooth and works without issues. In iOS 10 beta there's a jarring jump during the animation. Is there a way to fix this?

Here is a basic example of the code.

- (void)cellTapped {
[self.tableView beginUpdates];
[self.tableView endUpdates];

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return self.shouldExpandCell ? 200.0f : 100.0f;

Answer Source

With the iOS 10 beta nearing completion, hopefully this issue will be resolved in the next release. There's also an open bug report.

My solution involves dropping to the layer's CAAnimation. This will detect the change in height and automatically animate, just like using a CALayer unlinked to a UIView.

The first step is to adjust what happens when the layer detects a change. This code has to be in the subclass of your view. That view has to be a subview of your tableViewCell.contentView. In the code, we check if the view's layer's actions property has the key of our animation. If not just call super.

- (id<CAAction>)actionForLayer:(CALayer *)layer forKey:(NSString *)event {
    return [layer.actions objectForKey:event] ?: [super actionForLayer:layer forKey:event];

Next you want to add the animation to the actions property. You might find this code is best applied after the view is on the window and laid out. Applying it beforehand might lead to an animation as the view moves to the window.

- (void)didMoveToWindow {
    [super didMoveToWindow];

    if (self.window) {
        CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"bounds"];
        self.layer.actions = @{animation.keyPath:animation};

And that's it! No need to apply an animation.duration since the table view's -beginUpdates and -endUpdates overrides it. In general if you use this trick as a hassle-free way of applying animations, you will want to add an animation.duration and maybe also an animation.timingFunction.