How do you create a wiggle animation similar to iphone deletion animation
The answer by Vinzius is very cool. However the wobble only rotates from 0 Radians to 0.08. Thus the wobble can look a little unbalanced. If you get this same issue then you may want to add both a negative and a positive rotation by using a CAKeyframeAnimation rather than a CABasicRotation:
- (CAAnimation*)getShakeAnimation { CAKeyframeAnimation* animation = [CAKeyframeAnimation animationWithKeyPath:@"transform"]; CGFloat wobbleAngle = 0.06f; NSValue* valLeft = [NSValue valueWithCATransform3D:CATransform3DMakeRotation(wobbleAngle, 0.0f, 0.0f, 1.0f)]; NSValue* valRight = [NSValue valueWithCATransform3D:CATransform3DMakeRotation(-wobbleAngle, 0.0f, 0.0f, 1.0f)]; animation.values = [NSArray arrayWithObjects:valLeft, valRight, nil]; animation.autoreverses = YES; animation.duration = 0.125; animation.repeatCount = HUGE_VALF; return animation; }
You can use this animation method for your view or button like this.
[self.yourbutton.layer addAnimation:[self getShakeAnimation] forKey:@""];
SWIFT :-
let transformAnim = CAKeyframeAnimation(keyPath:"transform")transformAnim.values = [NSValue(CATransform3D: CATransform3DMakeRotation(0.04, 0.0, 0.0, 1.0)),NSValue(CATransform3D: CATransform3DMakeRotation(-0.04 , 0, 0, 1))]transformAnim.autoreverses = truetransformAnim.duration = (Double(indexPath.row)%2) == 0 ? 0.115 : 0.105transformAnim.repeatCount = Float.infinityself.layer.addAnimation(transformAnim, forKey: "transform")
Objective C :-
-(CAKeyframeAnimation *)wiggleView{ CAKeyframeAnimation* animation = [CAKeyframeAnimation animationWithKeyPath:@"transform"]; CGFloat wobbleAngle = 0.04f; NSValue* valLeft = [NSValue valueWithCATransform3D:CATransform3DMakeRotation(wobbleAngle, 0.0f, 0.0f, 1.0f)]; NSValue* valRight = [NSValue valueWithCATransform3D:CATransform3DMakeRotation(-wobbleAngle, 0.0f, 0.0f, 1.0f)]; animation.values = [NSArray arrayWithObjects:valLeft, valRight, nil]; animation.autoreverses = YES; animation.duration = 0.125; animation.repeatCount = HUGE_VALF; return animation;}
Looking at the iOS implementation a bit closer, there are two things that make theirs a bit more realistic than the code mentioned here:
- The icons appear to have a bounce as well as a rotation
- Every icon has its own timing -- they are not all synchronized
I based myself on the answers here (and with some help from this answer) to add the rotation, the bounce and a bit of randomness to the duration of each animation.
#define kWiggleBounceY 4.0f#define kWiggleBounceDuration 0.12#define kWiggleBounceDurationVariance 0.025#define kWiggleRotateAngle 0.06f#define kWiggleRotateDuration 0.1#define kWiggleRotateDurationVariance 0.025-(void)startWiggling { [UIView animateWithDuration:0 animations:^{ [self.layer addAnimation:[self rotationAnimation] forKey:@"rotation"]; [self.layer addAnimation:[self bounceAnimation] forKey:@"bounce"]; self.transform = CGAffineTransformIdentity; }];}-(CAAnimation*)rotationAnimation { CAKeyframeAnimation* animation = [CAKeyframeAnimation animationWithKeyPath:@"transform.rotation.z"]; animation.values = @[@(-kWiggleRotateAngle), @(kWiggleRotateAngle)]; animation.autoreverses = YES; animation.duration = [self randomizeInterval:kWiggleRotateDuration withVariance:kWiggleRotateDurationVariance]; animation.repeatCount = HUGE_VALF; return animation;}-(CAAnimation*)bounceAnimation { CAKeyframeAnimation* animation = [CAKeyframeAnimation animationWithKeyPath:@"transform.translation.y"]; animation.values = @[@(kWiggleBounceY), @(0.0)]; animation.autoreverses = YES; animation.duration = [self randomizeInterval:kWiggleBounceDuration withVariance:kWiggleBounceDurationVariance]; animation.repeatCount = HUGE_VALF; return animation;}-(NSTimeInterval)randomizeInterval:(NSTimeInterval)interval withVariance:(double)variance { double random = (arc4random_uniform(1000) - 500.0) / 500.0; return interval + variance * random;}
I implemented this code on a UICollectionView which had 30 items bouncing and the performance was flawless on an iPad 2.