UI基础--动画(缩放动画, 渐变动画, 左右振动, 移动动画, 组合动画)(封装好)
Posted Tracy-Mcgrady
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UI基础--动画(缩放动画, 渐变动画, 左右振动, 移动动画, 组合动画)(封装好)相关的知识,希望对你有一定的参考价值。
创建一个CAAnimation的类别
CAAnimation+HCAnimation
.h
#import <QuartzCore/QuartzCore.h> #import <UIKit/UIKit.h> typedef NS_ENUM(NSInteger, Axis) { AxisX = 0, ///< x轴 AxisY, ///< y轴 AxisZ ///< z轴 }; typedef NS_ENUM(NSInteger, ShakeDerection) { ShakeDerectionAxisX = 0, ///< 左右 ShakeDerectionAxisY, ///< 上下 }; @interface CAAnimation (HCAnimation) /** * 在具体的UIView上实现一个缩放的动画 *@param view 动画的载体 *@param scaleValue 最终缩放值 *@param repeat 动画循环次数,0表示无限循环 *@param duration 动画运行一次的时间 *@return void */ + (void)showScaleAnimationInView:(UIView *)view ScaleValue:(CGFloat)scaleValue Repeat:(CGFloat)repeat Duration:(CGFloat)duration; /** * 在具体的UIView上实现一个移动的动画 *@param view 动画的载体 *@param Position 最终停留的位置(中心点坐标) *@param repeat 动画循环次数,0表示无限循环 *@param duration 动画运行一次的时间 *@return void */ + (void)showMoveAnimationInView:(UIView *)view Position:(CGPoint)position Repeat:(CGFloat)repeat Duration:(CGFloat)duration; /** * 在具体的UIView上实现一个旋转的动画 *@param view 动画的载体 *@param degree 旋转的弧度 *@param direction 旋转的方向 *@param repeat 动画循环次数,0表示无限循环 *@param duration 动画运行一次的时间 *@return void */ + (void)showRotateAnimationInView:(UIView *)view Degree:(CGFloat)degree Direction:(Axis)direction Repeat:(CGFloat)repeat Duration:(CGFloat)duration; /** * 在具体的UIView上实现一个透明度渐变的动画 *@param view 动画的载体 *@param alpha 最终显示的透明度 *@param repeat 动画循环次数,0表示无限循环 *@param duration 动画运行一次的时间 *@return void */ + (void)showOpacityAnimationInView:(UIView *)view Alpha:(CGFloat)alpha Repeat:(CGFloat)repeat Duration:(CGFloat)duration; /** * 在具体的UIView上实现一个震动的动画 *@param view 动画的载体 *@param offset 震动的偏移量 *@param derection 震动方向 *@param repeat 动画循环次数,0表示无限循环 *@param duration 动画运行一次的时间 *@return void */ + (void)showShakeAnimationInView:(UIView *)view Offset:(CGFloat)offset Direction:(ShakeDerection)derection Repeat:(CGFloat)repeat Duration:(CGFloat)duration; /** *清除具体UIView上的所有动画 *@param view 实施清除的对象 *@return void */ + (void)clearAnimationInView:(UIView *)view; @end
.m
#import "CAAnimation+HCAnimation.h" @implementation CAAnimation (HCAnimation) + (void)showScaleAnimationInView:(UIView *)view ScaleValue:(CGFloat)scaleValue Repeat:(CGFloat)repeat Duration:(CGFloat)duration { if (repeat == 0) { repeat = MAXFLOAT; } CABasicAnimation *scaleAnimation = [CABasicAnimation animationWithKeyPath:@"transform.scale"]; ///动画的起始状态值 scaleAnimation.fromValue = [NSNumber numberWithFloat:1.0]; ///动画结束状态值 scaleAnimation.toValue = [NSNumber numberWithFloat:scaleValue]; ///循环动画执行方式,原路返回式(YES 注意:一去一回才算一个动画周期) 还是 再次从头开始(NO 注意:仅仅去一次就是一个动画周期) scaleAnimation.autoreverses = YES; ///动画结束后保持的状态:开始状态(kCAFillModeRemoved/kCAFillModeBackwards)、结束状态(kCAFillModeForwards/kCAFillModeBoth) scaleAnimation.fillMode = kCAFillModeForwards; scaleAnimation.removedOnCompletion = NO; ///动画循环次数(MAXFLOAT 意味无穷) scaleAnimation.repeatCount = repeat; ///一个动画持续时间 scaleAnimation.duration = duration; [view.layer addAnimation:scaleAnimation forKey:@"scaleAnimation"]; } + (void)showMoveAnimationInView:(UIView *)view Position:(CGPoint)position Repeat:(CGFloat)repeat Duration:(CGFloat)duration { if (repeat == 0) { repeat = MAXFLOAT; } CABasicAnimation *moveAnimation = [CABasicAnimation animationWithKeyPath:@"position"]; moveAnimation.fromValue = [NSValue valueWithCGPoint:view.layer.position]; moveAnimation.toValue = [NSValue valueWithCGPoint:position]; moveAnimation.autoreverses = YES; moveAnimation.fillMode = kCAFillModeForwards; moveAnimation.removedOnCompletion = NO; moveAnimation.repeatCount = repeat; moveAnimation.duration = duration; [view.layer addAnimation:moveAnimation forKey:@"moveAnimation"]; } + (void)showRotateAnimationInView:(UIView *)view Degree:(CGFloat)degree Direction:(Axis)direction Repeat:(CGFloat)repeat Duration:(CGFloat)duration { if (repeat == 0) { repeat = MAXFLOAT; } NSArray *axisArray = @[@"transform.rotation.x",@"transform.rotation.y",@"transform.rotation.z"]; CABasicAnimation *rotateAnimation = [CABasicAnimation animationWithKeyPath:axisArray[direction]]; rotateAnimation.fromValue = [NSNumber numberWithFloat:0.0]; rotateAnimation.toValue = [NSNumber numberWithFloat:degree]; rotateAnimation.autoreverses = YES; rotateAnimation.fillMode = kCAFillModeForwards; rotateAnimation.removedOnCompletion = NO; rotateAnimation.repeatCount = repeat; rotateAnimation.duration = duration; [view.layer addAnimation:rotateAnimation forKey:@"rotateAnimation"]; } + (void)showOpacityAnimationInView:(UIView *)view Alpha:(CGFloat)alpha Repeat:(CGFloat)repeat Duration:(CGFloat)duration { if (repeat == 0) { repeat = MAXFLOAT; } CABasicAnimation *animation=[CABasicAnimation animationWithKeyPath:@"opacity"]; animation.fromValue=[NSNumber numberWithFloat:1.0]; animation.toValue=[NSNumber numberWithFloat:alpha]; animation.repeatCount = repeat; animation.duration = duration; animation.removedOnCompletion=NO; animation.fillMode=kCAFillModeForwards; animation.timingFunction=[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionDefault]; animation.autoreverses=YES; [view.layer addAnimation:animation forKey:@"animation"]; } + (void)showShakeAnimationInView:(UIView *)view Offset:(CGFloat)offset Direction:(ShakeDerection)derection Repeat:(CGFloat)repeat Duration:(CGFloat)duration { if (repeat == 0) { repeat = MAXFLOAT; } NSAssert([view.layer isKindOfClass:[CALayer class]] , @"invalid target"); CGPoint originPos = CGPointZero; CGSize originSize = CGSizeZero; if ([view.layer isKindOfClass:[CALayer class]]) { originPos = [(CALayer *)view.layer position]; originSize = [(CALayer *)view.layer bounds].size; } CAKeyframeAnimation* animation = [CAKeyframeAnimation animation]; animation.keyPath = @"position"; //改变value来实现不同方向的震动 CGFloat offsetX = 0; CGFloat offsetY = 0; if (derection == ShakeDerectionAxisX) { offsetX = offset; }else if (derection == ShakeDerectionAxisY){ offsetY = offset; } animation.values = @[ [NSValue valueWithCGPoint:CGPointMake(originPos.x, originPos.y)], [NSValue valueWithCGPoint:CGPointMake(originPos.x-offsetX, originPos.y-offsetY)], [NSValue valueWithCGPoint:CGPointMake(originPos.x, originPos.y)], [NSValue valueWithCGPoint:CGPointMake(originPos.x+offsetX, originPos.y+offsetY)], [NSValue valueWithCGPoint:CGPointMake(originPos.x, originPos.y)] ]; animation.repeatCount = repeat; animation.duration = duration; animation.fillMode = kCAFillModeForwards; [view.layer addAnimation:animation forKey:@"animation"]; } + (void)clearAnimationInView:(UIView *)view { [view.layer removeAllAnimations]; } @end
在需要的地方调用就可以了.
#import "ViewController.h" #import "CAAnimation+HCAnimation.h" #define kBtnTag 0 #define kBtnSelectedTag 1 @interface ViewController () @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; self.btn1.tag = kBtnTag; self.btn2.tag = kBtnTag; self.btn3.tag = kBtnTag; self.btn4.tag = kBtnTag; self.btn5.tag = kBtnTag; self.btn6.tag = kBtnTag; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; } ///缩放动画 - (IBAction)btn1Clicked:(id)sender { UIButton *btn = (UIButton *)sender; if (btn.tag == kBtnTag) { [CAAnimation showScaleAnimationInView:btn ScaleValue:1.5 Repeat:0 Duration:0.8]; }else{ [CAAnimation clearAnimationInView:btn]; } btn.tag = btn.tag == kBtnTag ? kBtnSelectedTag : kBtnTag; } ///渐变动画 - (IBAction)btn2Clicked:(id)sender { UIButton *btn = (UIButton *)sender; if (btn.tag == kBtnTag) { [CAAnimation showOpacityAnimationInView:btn Alpha:0.1 Repeat:0 Duration:0.6]; }else{ [CAAnimation clearAnimationInView:btn]; } btn.tag = btn.tag == kBtnTag ? kBtnSelectedTag : kBtnTag; } ///左右震动动画 - (IBAction)btn3Clicked:(id)sender { UIButton *btn = (UIButton *)sender; if (btn.tag == kBtnTag) { [CAAnimation showShakeAnimationInView:btn Offset:10.0 Direction:ShakeDerectionAxisX Repeat:0 Duration:0.5]; }else{ [CAAnimation clearAnimationInView:btn]; } btn.tag = btn.tag == kBtnTag ? kBtnSelectedTag : kBtnTag; } ///移动动画 - (IBAction)btn4Clicked:(id)sender { UIButton *btn = (UIButton *)sender; if (btn.tag == kBtnTag) { [CAAnimation showMoveAnimationInView:btn Position:CGPointMake(btn.layer.position.x*2, btn.layer.position.y) Repeat:0 Duration:0.8]; }else{ [CAAnimation clearAnimationInView:btn]; } btn.tag = btn.tag == kBtnTag ? kBtnSelectedTag : kBtnTag; } ///组合动画 - (IBAction)btn5Clicked:(id)sender { UIButton *btn = (UIButton *)sender; if (btn.tag == kBtnTag) { [CAAnimation showScaleAnimationInView:btn ScaleValue:1.5 Repeat:0 Duration:1.0]; [CAAnimation showOpacityAnimationInView:btn Alpha:0.3 Repeat:0 Duration:1.0]; [CAAnimation showMoveAnimationInView:btn Position:self.btn1.layer.position Repeat:0 Duration:1.0]; [CAAnimation showRotateAnimationInView:btn Degree:2*M_PI Direction:AxisZ Repeat:0 Duration:1.0]; }else{ [CAAnimation clearAnimationInView:btn]; } btn.tag = btn.tag == kBtnTag ? kBtnSelectedTag : kBtnTag; } ///旋转动画 - (IBAction)btn6Clicked:(id)sender { UIButton *btn = (UIButton *)sender; if (btn.tag == kBtnTag) { [CAAnimation showRotateAnimationInView:btn Degree:2*M_PI Direction:AxisY Repeat:0 Duration:1.0]; }else{ [CAAnimation clearAnimationInView:btn]; } btn.tag = btn.tag == kBtnTag ? kBtnSelectedTag : kBtnTag; } @end
OK...
以上是关于UI基础--动画(缩放动画, 渐变动画, 左右振动, 移动动画, 组合动画)(封装好)的主要内容,如果未能解决你的问题,请参考以下文章