iOS Bounce Animation

Sep 3, 2012 · Follow on Twitter and Mastodon objc

I have an app with a main menu, where users can swipe horizontally through a set of icons that take the user to certain parts of the app. When an icon is tapped, it bounces, plays a sound and takes the user to that particular part of the app. Let’s see how the bounce animation was made.

After trying out many different animations, I fell in love with a nice and clean bounce animation that does its job without being too obvious. Unfortunately, the link to the original implementation is now dead.

I modified the code by creating a UIView category for the animation, and added a bounce factor so the effect can be used in various situations. I should probably do the same for the repeat count as well.

Here’s the code for the category:

UIView+Bounce.h:

#import <UIKit/UIKit.h>

@interface UIView (Bounce)

- (void)bounce:(float)bounceFactor;

@end

UIView+Bounce.m:

#import "UIView+Bounce.h"
#import <QuartzCore/QuartzCore.h>

@implementation UIView (Bounce)

+ (CAKeyframeAnimation*)dockBounceAnimationWithViewHeight:(CGFloat)viewHeight
{
    NSUInteger const kNumFactors    = 22;
    CGFloat const kFactorsPerSec    = 30.0f;
    CGFloat const kFactorsMaxValue  = 128.0f;
    CGFloat factors[kNumFactors]    = {0,  60, 83, 100, 114, 124, 128, 128, 124, 114, 100, 83, 60, 32, 0, 0, 18, 28, 32, 28, 18, 0};

    NSMutableArray* transforms = [NSMutableArray array];

    for(NSUInteger i = 0; i < kNumFactors; i++)
    {
        CGFloat positionOffset  = factors[i] / kFactorsMaxValue * viewHeight;
        CATransform3D transform = CATransform3DMakeTranslation(0.0f, -positionOffset, 0.0f);

        [transforms addObject:[NSValue valueWithCATransform3D:transform]];
    }

    CAKeyframeAnimation* animation = [CAKeyframeAnimation animationWithKeyPath:@"transform"];
    animation.repeatCount           = 1;
    animation.duration              = kNumFactors * 1.0f/kFactorsPerSec;
    animation.fillMode              = kCAFillModeForwards;
    animation.values                = transforms;
    animation.removedOnCompletion   = YES; // final stage is equal to starting stage
    animation.autoreverses          = NO;

    return animation;
}

- (void)bounce:(float)bounceFactor
{
    CGFloat midHeight = self.frame.size.height * bounceFactor;
    CAKeyframeAnimation* animation = [[self class] dockBounceAnimationWithViewHeight:midHeight];
    [self.layer addAnimation:animation forKey:@"bouncing"];
}

@end

Feel free to try it out. Hope you like it!

Discussions & More

Please share any ideas, feedback or comments you may have in the Disqus section below, or by replying on Twitter or Mastodon..

If you found this text interesting, make sure to follow me on Twitter and Mastodon for more content like this, and to be notified when new content is published.

If you like & want to support my work, please consider sponsoring me on GitHub Sponsors.