Created
April 22, 2014 20:27
-
-
Save r3econ/11193115 to your computer and use it in GitHub Desktop.
UIView Animation Extensions
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// Created by Rafal Sroka | |
// | |
// License CC0. | |
// This is free and unencumbered software released into the public domain. | |
// | |
// Anyone is free to copy, modify, publish, use, compile, sell, or | |
// distribute this software, either in source code form or as a compiled | |
// binary, for any purpose, commercial or non-commercial, and by any means. | |
// | |
/** | |
@brief Direction of flip animation. | |
*/ | |
typedef NS_ENUM(NSUInteger, UIViewAnimationFlipDirection) | |
{ | |
UIViewAnimationFlipDirectionFromTop, | |
UIViewAnimationFlipDirectionFromLeft, | |
UIViewAnimationFlipDirectionFromRight, | |
UIViewAnimationFlipDirectionFromBottom, | |
}; | |
/** | |
@brief Direction of rotation animation. | |
*/ | |
typedef NS_ENUM(NSUInteger, UIViewAnimationRotationDirection) | |
{ | |
UIViewAnimationRotationDirectionRight, | |
UIViewAnimationRotationDirectionLeft | |
}; | |
@interface UIView (AnimationExtensions) | |
/** | |
@brief Shakes the view horizontally for a short period of time. | |
*/ | |
- (void)shakeHorizontally; | |
/** | |
@brief Shakes the view vertically for a short period of time. | |
*/ | |
- (void)shakeVertically; | |
/** | |
@brief Adds a motion effect to the view. Similar effect can be seen in the | |
background of the Home Screen on iOS 7. | |
@note Motion effects are available starting from iOS 7. Calling this method on | |
older iOS will be ignored. | |
*/ | |
- (void)applyMotionEffects; | |
/** | |
@brief Performs a pulsing scale animation on a view. | |
@param duration - duration of the animation | |
@param repeat - pass YES for the animation to repeat. | |
*/ | |
- (void)pulseToSize:(CGFloat)scale | |
duration:(NSTimeInterval)duration | |
repeat:(BOOL)repeat; | |
/** | |
@brief Performs a 3D-like flip animation of the view around center X or Y axis. | |
@param duration - total time of the animation. | |
@param direction - direction of the flip movement. | |
@param repeatCount - number of repetitions of the animation. Pass HUGE_VALF to repeat forever. | |
@param shouldAutoreverse - pass YES to make the animation reverse when it reaches the end. | |
*/ | |
- (void)flipWithDuration:(NSTimeInterval)duration | |
direction:(UIViewAnimationFlipDirection)direction | |
repeatCount:(NSUInteger)repeatCount | |
autoreverse:(BOOL)shouldAutoreverse; | |
/** | |
@brief Performs a rotation animation of the view around its anchor point. | |
@param angle - end angle of the rotation. Pass M_PI * 2.0 for full circle rotation. | |
@param duration - total time of the animation. | |
@param direction - left or right direction of the rotation. | |
@param repeatCount - number of repetitions of the animation. Pass HUGE_VALF to repeat forever. | |
@param shouldAutoreverse - pass YES to make the animation reverse when it reaches the end. | |
*/ | |
- (void)rotateToAngle:(CGFloat)angle | |
duration:(NSTimeInterval)duration | |
direction:(UIViewAnimationRotationDirection)direction | |
repeatCount:(NSUInteger)repeatCount | |
autoreverse:(BOOL)shouldAutoreverse; | |
/** | |
@brief Stops current animations. | |
*/ | |
- (void)stopAnimation; | |
/** | |
@brief Checks if the view is being animated. | |
*/ | |
- (BOOL)isBeingAnimated; | |
@end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// Created by Rafal Sroka | |
// | |
// License CC0. | |
// This is free and unencumbered software released into the public domain. | |
// | |
// Anyone is free to copy, modify, publish, use, compile, sell, or | |
// distribute this software, either in source code form or as a compiled | |
// binary, for any purpose, commercial or non-commercial, and by any means. | |
// | |
#import "UIView+AnimationExtensions.h" | |
@implementation UIView (AnimationExtensions) | |
- (void)shakeHorizontally | |
{ | |
CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"transform.translation.x"]; | |
animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]; | |
animation.duration = 0.5; | |
animation.values = @[@(-12), @(12), @(-8), @(8), @(-4), @(4), @(0) ]; | |
[self.layer addAnimation:animation forKey:@"shake"]; | |
} | |
- (void)shakeVertically | |
{ | |
CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"transform.translation.y"]; | |
animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]; | |
animation.duration = 0.5; | |
animation.values = @[@(-12), @(12), @(-8), @(8), @(-4), @(4), @(0) ]; | |
[self.layer addAnimation:animation forKey:@"shake"]; | |
} | |
- (void)applyMotionEffects | |
{ | |
// Motion effects are available starting from iOS 7. | |
if (([[[UIDevice currentDevice] systemVersion] compare:@"7.0" options:NSNumericSearch] != NSOrderedAscending)) | |
{ | |
UIInterpolatingMotionEffect *horizontalEffect = [[UIInterpolatingMotionEffect alloc] initWithKeyPath:@"center.x" | |
type:UIInterpolatingMotionEffectTypeTiltAlongHorizontalAxis]; | |
horizontalEffect.minimumRelativeValue = @(-10.0f); | |
horizontalEffect.maximumRelativeValue = @( 10.0f); | |
UIInterpolatingMotionEffect *verticalEffect = [[UIInterpolatingMotionEffect alloc] initWithKeyPath:@"center.y" | |
type:UIInterpolatingMotionEffectTypeTiltAlongVerticalAxis]; | |
verticalEffect.minimumRelativeValue = @(-10.0f); | |
verticalEffect.maximumRelativeValue = @( 10.0f); | |
UIMotionEffectGroup *motionEffectGroup = [[UIMotionEffectGroup alloc] init]; | |
motionEffectGroup.motionEffects = @[horizontalEffect, verticalEffect]; | |
[self addMotionEffect:motionEffectGroup]; | |
} | |
} | |
- (void)pulseToSize:(CGFloat)scale | |
duration:(NSTimeInterval)duration | |
repeat:(BOOL)repeat | |
{ | |
CABasicAnimation *pulseAnimation = [CABasicAnimation animationWithKeyPath:@"transform.scale"]; | |
pulseAnimation.duration = duration; | |
pulseAnimation.toValue = [NSNumber numberWithFloat:scale]; | |
pulseAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; | |
pulseAnimation.autoreverses = YES; | |
pulseAnimation.repeatCount = repeat ? HUGE_VALF : 0; | |
[self.layer addAnimation:pulseAnimation | |
forKey:@"pulse"]; | |
} | |
- (void)flipWithDuration:(NSTimeInterval)duration | |
direction:(UIViewAnimationFlipDirection)direction | |
repeatCount:(NSUInteger)repeatCount | |
autoreverse:(BOOL)shouldAutoreverse | |
{ | |
NSString *subtype = nil; | |
switch (direction) | |
{ | |
case UIViewAnimationFlipDirectionFromTop: | |
subtype = @"fromTop"; | |
break; | |
case UIViewAnimationFlipDirectionFromLeft: | |
subtype = @"fromLeft"; | |
break; | |
case UIViewAnimationFlipDirectionFromBottom: | |
subtype = @"fromBottom"; | |
break; | |
case UIViewAnimationFlipDirectionFromRight: | |
default: | |
subtype = @"fromRight"; | |
break; | |
} | |
CATransition *transition = [CATransition animation]; | |
transition.startProgress = 0; | |
transition.endProgress = 1.0; | |
transition.type = @"flip"; | |
transition.subtype = subtype; | |
transition.duration = duration; | |
transition.repeatCount = repeatCount; | |
transition.autoreverses = shouldAutoreverse; | |
[self.layer addAnimation:transition | |
forKey:@"spin"]; | |
} | |
- (void)rotateToAngle:(CGFloat)angle | |
duration:(NSTimeInterval)duration | |
direction:(UIViewAnimationRotationDirection)direction | |
repeatCount:(NSUInteger)repeatCount | |
autoreverse:(BOOL)shouldAutoreverse; | |
{ | |
CABasicAnimation *rotationAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"]; | |
rotationAnimation.toValue = @(direction == UIViewAnimationRotationDirectionRight ? angle : -angle); | |
rotationAnimation.duration = duration; | |
rotationAnimation.autoreverses = shouldAutoreverse; | |
rotationAnimation.repeatCount = repeatCount; | |
rotationAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; | |
[self.layer addAnimation:rotationAnimation | |
forKey:@"transform.rotation.z"]; | |
} | |
- (void)stopAnimation | |
{ | |
[CATransaction begin]; | |
[self.layer removeAllAnimations]; | |
[CATransaction commit]; | |
[CATransaction flush]; | |
} | |
- (BOOL)isBeingAnimated | |
{ | |
return [self.layer.animationKeys count]; | |
} | |
@end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment