Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to change the speed of the animations for UICollectionViews?

I am speaking of things like insertItemsAtIndexPaths or moveItemAtIndexPath:toIndexPath:. I have tried wrapping it in an animation block, but that did not work. It seems the animations are stuck at .25 or .3 seconds, but I would like to slow this. Other than implementing the movement myself, which isn't worth the trouble, does anyone know if this is possible with public APIs?

like image 799
akaru Avatar asked Sep 22 '12 20:09

akaru


1 Answers

Absolutely! But you can't do it properly using UIView animation blocks. You need to dig into Core Animation.

The collection view helpfully adds animations to the CALayer that is backing each UICollectionViewCell. But if you implement your own layout (or subclass an existing) you can do all the necessary modifications to these animations in the finalizeCollectionViewUpdates method.

From the UICollectionViewLayout class documentation:

The collection view calls this method as the last step before preceding to animate any changes into place.

Here is an example of how to replace the default position animation with your own:

- (void)finalizeCollectionViewUpdates
{
    for (UICollectionViewCell *cell in [self.collectionView visibleCells])
    {
        CAAnimation *positionAnimation = [cell.layer animationForKey:@"position"];
        if (positionAnimation)
        {
            [cell.layer removeAnimationForKey:@"position"];

            CALayer *presentationLayer = cell.layer.presentationLayer;
            CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"position"];
            [animation setFromValue:[NSValue valueWithCGPoint:presentationLayer.position]];
            [animation setToValue:[NSValue valueWithCGPoint:cell.layer.position]];
            [animation setDuration:0.4];

            [cell.layer addAnimation:animation forKey:@"position"];
        }
    }
}

Look at the animation-related methods on CALayer to see how you can dig into what animations are currently running on your layer.

Using this approach you could even get creative and add overshoot/bounce effects using CAKeyframeAnimation or anything else you can think of. You could also do things like selectively disable some animations (like size) and keep others (like position).

like image 104
Heiberg Avatar answered Jan 01 '23 06:01

Heiberg