UIView Animating a 2D Bouncing Ball (Squash & Stretch) in iOS


Looking for Animating a view like Bouncing Ball using Squash & Stretch, in cocoa using core animation...

1 - Bouncing Ball Animation

Bouncing Ball Animation ;;;;

CABasicAnimation *animMoveUp = [CABasicAnimation animationWithKeyPath:@"position"];
animMoveUp.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];
animMoveUp.fromValue   =   [NSValue valueWithCGPoint:_bottom];
animMoveUp.toValue     =   [NSValue valueWithCGPoint:_top];

CABasicAnimation *scaleAnim1 = [CABasicAnimation animationWithKeyPath:@"transform"];
scaleAnim1.toValue      = [NSValue valueWithCATransform3D:CATransform3DMakeScale(2.5, 2.0, 1.0)];
scaleAnim1.toValue      =   [NSValue valueWithCATransform3D:CATransform3DMakeScale(2.0, 2.0, 1.0)];

CABasicAnimation *bounceAnim1 = [CABasicAnimation animationWithKeyPath:@"transform"];
bounceAnim1.fromValue   = [NSValue valueWithCATransform3D:CATransform3DMakeScale(2.0, 2.0, 1.0)];
bounceAnim1.toValue     = [NSValue valueWithCATransform3D:CATransform3DMakeScale(3.0, 1.0, 1.0)];

CABasicAnimation *animMoveDown = [CABasicAnimation animationWithKeyPath:@"position"];
animMoveDown.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
animMoveDown.fromValue   =   [NSValue valueWithCGPoint:_top];
animMoveDown.toValue     =   [NSValue valueWithCGPoint:_bottom];


CABasicAnimation *scaleAnim2 = [CABasicAnimation animationWithKeyPath:@"transform"];
scaleAnim2.fromValue    =   [NSValue valueWithCATransform3D:CATransform3DMakeScale(2.5, 2.0, 1.0)];
scaleAnim2.toValue      =   [NSValue valueWithCATransform3D:CATransform3DMakeScale(2.0, 2.0, 1.0)];

CABasicAnimation *bounceAnim2 = [CABasicAnimation animationWithKeyPath:@"transform"];
bounceAnim2.fromValue   =   [NSValue valueWithCATransform3D:CATransform3DMakeScale(2.0, 2.0, 1.0)];
bounceAnim2.toValue     =   [NSValue valueWithCATransform3D:CATransform3DMakeScale(3.0, 1.0, 1.0)];

CABasicAnimation *animMoveUp1 = [CABasicAnimation animationWithKeyPath:@"position"];
animMoveUp1.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
animMoveUp1.fromValue   =   [NSValue valueWithCGPoint:_bottom];
animMoveUp1.toValue     =   [NSValue valueWithCGPoint:_top];

CABasicAnimation *scaleAnim3 = [CABasicAnimation animationWithKeyPath:@"transform"];
scaleAnim3.fromValue    =   [NSValue valueWithCATransform3D:CATransform3DMakeScale(2.5, 2.0, 1.0)];
scaleAnim3.toValue      =   [NSValue valueWithCATransform3D:CATransform3DMakeScale(2.0, 2.0, 1.0)];

CABasicAnimation *bounceAnim3 = [CABasicAnimation animationWithKeyPath:@"transform"];
bounceAnim3.fromValue   =   [NSValue valueWithCATransform3D:CATransform3DMakeScale(2.0, 2.0, 1.0)];
bounceAnim3.toValue     =   [NSValue valueWithCATransform3D:CATransform3DMakeScale(3.0, 1.0, 1.0)];

CABasicAnimation *animMoveDown2 = [CABasicAnimation animationWithKeyPath:@"position"];
animMoveDown2.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
animMoveDown2.fromValue   =   [NSValue valueWithCGPoint:_top];
animMoveDown2.toValue     =   [NSValue valueWithCGPoint:_bottom];

CABasicAnimation *scaleAnim4 = [CABasicAnimation animationWithKeyPath:@"transform"];
scaleAnim4.fromValue    =   [NSValue valueWithCATransform3D:CATransform3DMakeScale(2.5, 2.0, 1.0)];
scaleAnim4.toValue      =   [NSValue valueWithCATransform3D:CATransform3DMakeScale(2.0, 2.0, 1.0)];

CABasicAnimation *bounceAnim4 = [CABasicAnimation animationWithKeyPath:@"transform"];
bounceAnim4.fromValue   =   [NSValue valueWithCATransform3D:CATransform3DMakeScale(2.0, 2.0, 1.0)];
bounceAnim4.toValue     =   [NSValue valueWithCATransform3D:CATransform3DMakeScale(3.0, 1.0, 1.0)];

CAAnimationGroup *animGroup = [CAAnimationGroup animation];

animGroup.animations = @[animMoveUp,    scaleAnim1,     bounceAnim1,
                         animMoveDown,  scaleAnim2,     bounceAnim2,
                         animMoveUp1,   scaleAnim3,     bounceAnim3,
                         animMoveDown2, scaleAnim4,     bounceAnim4];

animGroup.duration      =   2.5;
animGroup.delegate      =   self;
animGroup.fillMode      =   kCAFillModeForwards;

animGroup.removedOnCompletion = NO;

[_imgView.layer addAnimation:animGroup forKey:nil];

Answers:


enter image description here

The following code will generate the animation above:

CAKeyframeAnimation *trans = [CAKeyframeAnimation animationWithKeyPath:@"transform.translation.y"];
NSArray *values = @[@(-200),@(20),@(0)];
trans.values = values;
NSArray *times = @[@(0.0),@(0.85),@(1)];
trans.keyTimes = times;
trans.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
trans.autoreverses = YES;
trans.duration = 1.0;
trans.repeatCount = INFINITY;

CAKeyframeAnimation *scaleXAnimation = [CAKeyframeAnimation animationWithKeyPath:@"transform.scale.x"];
NSArray *scaleXValues = @[@(0.75),@(0.75),@(1)];
scaleXAnimation.values = scaleXValues;
NSArray *scaleXtimes = @[@(0.0),@(0.85),@(1)];
scaleXAnimation.keyTimes = scaleXtimes;
scaleXAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
scaleXAnimation.autoreverses = YES;
scaleXAnimation.duration = 1.0;
scaleXAnimation.repeatCount = INFINITY;

CAKeyframeAnimation *scaleYAnimation = [CAKeyframeAnimation animationWithKeyPath:@"transform.scale.y"];
NSArray *scaleYValues = @[@(0.75),@(1),@(0.85)];
scaleYAnimation.values = scaleYValues;
NSArray *scaleYtimes = @[@(0.1),@(0.5),@(1)];
scaleYAnimation.keyTimes = scaleYtimes;
scaleYAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
scaleYAnimation.autoreverses = YES;
scaleYAnimation.duration = 1.0;
scaleYAnimation.repeatCount = INFINITY;

[_ballView.layer addAnimation:scaleXAnimation forKey:@"scaleX"];
[_ballView.layer addAnimation:scaleYAnimation forKey:@"scaleY"];
[_ballView.layer addAnimation:trans forKey:@"trans"];