300字范文,内容丰富有趣,生活中的好帮手!
300字范文 > iOS动画(Core Animation)使用

iOS动画(Core Animation)使用

时间:2019-10-24 23:59:00

相关推荐

iOS动画(Core Animation)使用

一、简介

IOS 动画主要是指Core Animation框架。官方使用文档地址为:Core Animation Guide。

Core Animation是IOS和OS X平台上负责图形渲染与动画的基础框架。Core Animation可以作用与动画视图或者其他可视元素,为你完成了动画所需的大部分绘帧工作。你只需要配置少量的动画参数(如开始点的位置和结束点的位置)即可使用Core Animation的动画效果。Core Animation将大部分实际的绘图任务交给了图形硬件来处理,图形硬件会加速图形渲染的速度。这种自动化的图形加速技术让动画拥有更高的帧率并且显示效果更加平滑,不会加重CPU的负担而影响程序的运行速度。

二、Core Animation类图以及常用字段

Core Animation类的继承关系图

常用属性duration : 动画的持续时间 beginTime : 动画的开始时间 repeatCount : 动画的重复次数 autoreverses : 执行的动画按照原动画返回执行 timingFunction : 控制动画的显示节奏系统提供五种值选择,分别是:

kCAMediaTimingFunctionLinear 线性动画kCAMediaTimingFunctionEaseIn 先慢后快(慢进快出)kCAMediaTimingFunctionEaseOut 先块后慢(快进慢出)kCAMediaTimingFunctionEaseInEaseOut 先慢后快再慢kCAMediaTimingFunctionDefault 默认,也属于中间比较快

delegate : 动画代理。能够检测动画的执行和结束。

/* Delegate methods for CAAnimation. */@interface NSObject (CAAnimationDelegate)/* Called when the animation begins its active duration. */- (void)animationDidStart:(CAAnimation *)anim;/* Called when the animation either completes its active duration or* is removed from the object it is attached to (i.e. the layer). 'flag'* is true if the animation reached the end of its active duration* without being removed. */- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag;@end

path:关键帧动画中的执行路径 type : 过渡动画的动画类型,系统提供了四种过渡动画。

kCATransitionFade 渐变效果kCATransitionMoveIn 进入覆盖效果kCATransitionPush 推出效果kCATransitionReveal 揭露离开效果 subtype : 过渡动画的动画方向kCATransitionFromRight 从右侧进入kCATransitionFromLeft 从左侧进入kCATransitionFromTop 从顶部进入kCATransitionFromBottom 从底部进入

三、IOS动画的调用方式

第一种:UIView 代码块调用

_demoView.frame = CGRectMake(0, SCREEN_HEIGHT/2-50, 50, 50);[UIView animateWithDuration:1.0f animations:^{_demoView.frame = CGRectMake(SCREEN_WIDTH, SCREEN_HEIGHT/2-50, 50, 50);} completion:^(BOOL finished) {_demoView.frame = CGRectMake(SCREEN_WIDTH/2-25, SCREEN_HEIGHT/2-50, 50, 50);}];

第二种:UIView [begin commit]模式

[UIView beginAnimations:@"move" context:nil];[UIView setAnimationDuration:2];[UIView setAnimationDelegate:self];//改变它的frame的x,y的值animationView.frame = CGRectMake(100, 100, 120, 100);[UIView commitAnimations];

第三种:使用Core Animation中的类

<pre name="code" class="objc"> // time:闪烁间隔 repeatCount = MAXFLOAT(永久闪烁)CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"opacity"];//这是透明度值得变化。animation.fromValue = [NSNumber numberWithFloat:1.0f];animation.toValue = [NSNumber numberWithFloat:0.0f];//是否自动倒退animation.autoreverses = YES;animation.duration = time;animation.repeatCount = repeatCount;//动画执行完毕之后不删除动画animation.removedOnCompletion = NO;animation.fillMode = kCAFillModeForwards;//没有的话是均匀的动画。animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];

四、iOS动画的使用

4.1:基础动画(CABaseAnimation)

重要属性 fromValue : keyPath对应的初始值 toValue : keyPath对应的结束值

基础动画主要提供了对于CALayer对象中的可变属性进行简单动画的操作。比如:位移、透明度、缩放、旋转、背景色等等。 效果演示:

位移动画代码演示:

//使用CABasicAnimation创建基础动画CABasicAnimation *anima = [CABasicAnimation animationWithKeyPath:@"position"];anima.fromValue = [NSValue valueWithCGPoint:CGPointMake(0, SCREEN_HEIGHT/2-75)];anima.toValue = [NSValue valueWithCGPoint:CGPointMake(SCREEN_WIDTH, SCREEN_HEIGHT/2-75)];anima.duration = 1.0f;//anima.fillMode = kCAFillModeForwards;//anima.removedOnCompletion = NO;[_demoView.layer addAnimation:anima forKey:@"positionAnimation"];

注意点 如果fillMode=kCAFillModeForwards和removedOnComletion=NO,那么在动画执行完毕后,图层会保持显示动画执行后的状态。但在实质上,图层的属性值还是动画执行前的初始值,并没有真正被改变。

4.2:关键帧动画(CAKeyframeAnimation)

CAKeyframeAnimation和CABaseAnimation都属于CAPropertyAnimatin的子类。CABaseAnimation只能从一个数值(fromValue)变换成另一个数值(toValue),而CAKeyframeAnimation则会使用一个NSArray保存一组关键帧。

重要属性values: 就是上述的NSArray对象。里面的元素称为”关键帧”(keyframe)。动画对象会在指定的时间(duration)内,依次显示values数组中的每一个关键帧

path: 可以设置一个CGPathRef\CGMutablePathRef,让层跟着路径移动。path只对CALayer的anchorPoint和position起作用。如果你设置了path,那么values将被忽略。

keyTimes: 可以为对应的关键帧指定对应的时间点,其取值范围为0到1.0,keyTimes中的每一个时间值都对应values中的每一帧.当keyTimes没有设置的时候,各个关键帧的时间是平分的。

效果演示:

圆形路径动画代码演示:

CAKeyframeAnimation *anima = [CAKeyframeAnimation animationWithKeyPath:@"position"];UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(SCREEN_WIDTH/2-100, SCREEN_HEIGHT/2-100, 200, 200)];anima.path = path.CGPath;anima.duration = 2.0f;[_demoView.layer addAnimation:anima forKey:@"pathAnimation"];

说明 :CABasicAnimation可看做是最多只有2个关键帧的CAKeyframeAnimation

4.3:组动画(CAAnimationGroup)

CAAnimation的子类,可以保存一组动画对象,将CAAnimationGroup对象加入层后,组中所有动画对象可以同时并发运行。

重要属性animations: 用来保存一组动画对象的NSArray

效果演示:

组动画代码演示:

CAKeyframeAnimation *anima1 = [CAKeyframeAnimation animationWithKeyPath:@"position"];NSValue *value0 = [NSValue valueWithCGPoint:CGPointMake(0, SCREEN_HEIGHT/2-50)];NSValue *value1 = [NSValue valueWithCGPoint:CGPointMake(SCREEN_WIDTH/3, SCREEN_HEIGHT/2-50)];NSValue *value2 = [NSValue valueWithCGPoint:CGPointMake(SCREEN_WIDTH/3, SCREEN_HEIGHT/2+50)];NSValue *value3 = [NSValue valueWithCGPoint:CGPointMake(SCREEN_WIDTH*2/3, SCREEN_HEIGHT/2+50)];NSValue *value4 = [NSValue valueWithCGPoint:CGPointMake(SCREEN_WIDTH*2/3, SCREEN_HEIGHT/2-50)];NSValue *value5 = [NSValue valueWithCGPoint:CGPointMake(SCREEN_WIDTH, SCREEN_HEIGHT/2-50)];anima1.values = [NSArray arrayWithObjects:value0,value1,value2,value3,value4,value5, nil];//缩放动画CABasicAnimation *anima2 = [CABasicAnimation animationWithKeyPath:@"transform.scale"];anima2.fromValue = [NSNumber numberWithFloat:0.8f];anima2.toValue = [NSNumber numberWithFloat:2.0f];//旋转动画CABasicAnimation *anima3 = [CABasicAnimation animationWithKeyPath:@"transform.rotation"];anima3.toValue = [NSNumber numberWithFloat:M_PI*4];//组动画CAAnimationGroup *groupAnimation = [CAAnimationGroup animation];groupAnimation.animations = [NSArray arrayWithObjects:anima1,anima2,anima3, nil];groupAnimation.duration = 4.0f;[_demoView.layer addAnimation:groupAnimation forKey:@"groupAnimation"];

4.4:过渡动画(CATransition)

CAAnimation的子类,用于做过渡动画或者转场动画,能够为层提供移出屏幕和移入屏幕的动画效果。重要属性type:动画过渡类型

Apple 官方的SDK其实只提供了四种过渡效果。

kCATransitionFade 渐变效果 kCATransitionMoveIn 进入覆盖效果kCATransitionPush 推出效果kCATransitionReveal 揭露离开效果 私有API提供了其他很多非常炫的过渡动画,比如@"cube"、@"suckEffect"、@"oglFlip"、 @"rippleEffect"、@"pageCurl"、@"pageUnCurl"、@"cameraIrisHollowOpen"、@"cameraIrisHollowClose"等。注意点私有api,不建议开发者们使用。因为苹果公司不提供维护,并且有可能造成你的app审核不通过。

subtype:动画过渡方向

kCATransitionFromRight 从右侧进入kCATransitionFromLeft 从左侧进入kCATransitionFromTop 从顶部进入kCATransitionFromBottom 从底部进入

startProgress:动画起点(在整体动画的百分比)endProgress:动画终点(在整体动画的百分比)

效果演示:

4.5:综合案例

4.5.1 : 仿Path菜单效果
效果演示:

动画解析: 1、点击红色按钮,红色按钮旋转。(旋转动画) 2、黑色小按钮依次弹出,并且带有旋转效果。(位移动画、旋转动画、组动画) 3、点击黑色小按钮,其他按钮消失,被点击的黑色按钮变大变淡消失。(缩放动画、alpha动画、组动画)博主的话:代码过多,这里不做演示。文章最后提供代码下载地址。

4.5.2: 仿钉钉菜单效果
效果演示:

看上去挺炫的,其实实现很简单,就是位移动画+缩放动画。

4.5.3: 点赞烟花效果动画
效果演示:

这里其实只有按钮变大效果使用的缩放动画。烟花效果 使用的是一种比较特殊的动画--粒子动画。 一个粒子系统一般有两部分组成: 1、CAEmitterCell:可以看作是单个粒子的原型(例如,一个单一的粉扑在一团烟雾)。当散发出一个粒子,UIKit根据这个发射粒子和定义的基础上创建一个随机粒子。此原型包括一些属性来控制粒子的图片,颜色,方向,运动,缩放比例和生命周期。 2、CAEmitterLayer:主要控制发射源的位置、尺寸、发射模式、发射源的形状等等。 以上两个类的属性还是比较多的,这里就不细讲了。大家可以google一下,详细的了解吧。

五、总结

任何复杂的动画其实都是由一个个简单的动画组装而成的,只要我们善于分解和组装,我们就能实现出满意的效果。动画其实也不是那么难。

六、常用动画代码

以下是自己封装了一些常用动画管理类

//

// AnimationManager.h

// redlips

//

// Created by zizp on 15/12/23.

// Copyright © xiaohongchun. All rights reserved.

//

#import <Foundation/Foundation.h>@interface AnimationManager : NSObject/* 闪烁动画* time:闪烁间隔* repeatCount = MAXFLOAT(永久闪烁)重复次数*/+ (CABasicAnimation *)opacityForever_Animation:(CGFloat)time repeatCount:(CGFloat)repeatCount;/* 横向、纵向移动* time:* x,y : 终点*/+ (CABasicAnimation *)moveX:(CGFloat)time X:(NSNumber *)x;+ (CABasicAnimation *)moveY:(CGFloat)time Y:(NSNumber *)y;/* 缩放* time:* Multiple: fromValue* orginMultiple: toValue* repeatTimes: 重复次数*/+ (CABasicAnimation *)scale:(NSNumber *)Multiple orgin:(NSNumber *)orginMultiple durTimes:(CGFloat)time Rep:(CGFloat)repertTimes;/* 组合动画* time:* animationAry: 动画组* repeatTimes: 重复次数*/+ (CAAnimationGroup *)groupAnimation:(NSArray *)animationAry durTimes:(CGFloat)time Rep:(CGFloat)repeatTimes;/* 路径动画* path: 路径* time:* repeatTimes: 重复次数*/+ (CAKeyframeAnimation *)keyframeAnimation:(CGMutablePathRef)path durTimes:(CGFloat)time Rep:(CGFloat)repeatTimes;/* 旋转动画* time:* degree: 角度* direction: 方向* repeatTimes: 重复次数*/+ (CABasicAnimation *)rotation:(CGFloat)time degree:(CGFloat)degree direction:(CGFloat)direction repeatCount:(CGFloat)repeatCount;@end

//

// AnimationManager.m

// redlips

//

// Created by zizp on 15/12/23.

// Copyright © xiaohongchun. All rights reserved.

//

#import "AnimationManager.h"static NSString * const kAnimationWithKeyPathRotation_X = @"transform.rotation.x";/**< The rotation, in radians, in the x axis. */static NSString * const kAnimationWithKeyPathRotation_Y = @"transform.rotation.y";/**< The rotation, in radians, in the y axis. */static NSString * const kAnimationWithKeyPathRotation_Z = @"transform.rotation.z";/**< The rotation, in radians, in the z axis. */static NSString * const kAnimationWithKeyPathRotation = @"transform.rotation"; /**< The rotation, in radians, in the z axis. This is identical to setting the rotation.z field */static NSString * const kAnimationWithKeyPathScale_X = @"transform.scale.x"; /**< Scale factor for the x axis. */static NSString * const kAnimationWithKeyPathScale_Y = @"transform.scale.y"; /**< Scale factor for the y axis. */static NSString * const kAnimationWithKeyPathScale_Z = @"transform.scale.z"; /**< Scale factor for the z axis. */static NSString * const kAnimationWithKeyPathScale= @"transform.scale"; /**< Average of all three scale factors */static NSString * const kAnimationWithKeyPathTranslation_X = @"transform.translation.x";/**< Translate in the x axis */static NSString * const kAnimationWithKeyPathTranslation_Y = @"transform.translation.y";/**< Translate in the y axis */static NSString * const kAnimationWithKeyPathTranslation_Z = @"transform.translation.z";/**< Translate in the z axis */static NSString * const kAnimationWithKeyPathTranslation = @"transform.translation"; /**< Translate in the x and y axis. Value is an CGPoint*/static NSString * const kAnimationWithKeyPathOpacity = @"opacity"; /**< 闪烁 */static NSString * const kAnimationWithKeyPathPosition = @"position";/**< 路径 */static NSString * const kAnimationWithKeyPathTransform = @"transform";/**< 旋转 */@implementation AnimationManager#pragma mark ====== 闪烁的动画 ======+ (CABasicAnimation *)opacityForever_Animation:(CGFloat)time repeatCount:(CGFloat)repeatCount{// time:闪烁间隔 repeatCount = MAXFLOAT(永久闪烁)CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"opacity"];//这是透明度值得变化。animation.fromValue = [NSNumber numberWithFloat:1.0f];animation.toValue = [NSNumber numberWithFloat:0.0f];//是否自动倒退animation.autoreverses = YES;animation.duration = time;animation.repeatCount = repeatCount;//动画执行完毕之后不删除动画animation.removedOnCompletion = NO;animation.fillMode = kCAFillModeForwards;//没有的话是均匀的动画。animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];return animation;}#pragma mark ====== 横向、纵向移动 ======+ (CABasicAnimation *)moveX:(CGFloat)time X:(NSNumber *)x{// .y 的话就向下移动。CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform.translation.x" ];animation.toValue = x;animation.duration = time;//是否删除动画(若为 YES 则动画完成后返回设定的 frame)animation.removedOnCompletion = NO;animation.repeatCount = MAXFLOAT ;animation.fillMode = kCAFillModeForwards ;return animation;}+ (CABasicAnimation *)moveY:(CGFloat)time Y:(NSNumber *)y{// .y 的话就向下移动。CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform.translation.y" ];animation.toValue = y;animation.duration = time;//是否删除动画(若为 YES 则动画完成后返回设定的 frame)animation.removedOnCompletion = NO;animation.repeatCount = MAXFLOAT ;animation.fillMode = kCAFillModeForwards ;return animation;}#pragma mark ====== 缩放 ======+ (CABasicAnimation *)scale:(NSNumber *)Multiple orgin:(NSNumber *)orginMultiple durTimes:(CGFloat)time Rep:(CGFloat)repertTimes{CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform.scale" ];animation.fromValue = Multiple;animation.toValue = orginMultiple;//是否自动倒退animation.autoreverses = YES;animation.repeatCount = repertTimes;animation.duration = time; // 不设置时候的话,有一个默认的缩放时间.animation.removedOnCompletion = NO;animation.fillMode = kCAFillModeForwards;return animation;}#pragma mark ====== 组合动画 ======+ (CAAnimationGroup *)groupAnimation:(NSArray *)animationAry durTimes:(CGFloat)time Rep:(CGFloat)repeatTimes{CAAnimationGroup *animation = [CAAnimationGroup animation];animation.animations = animationAry;animation.duration = time;animation.removedOnCompletion = NO;animation.repeatCount = repeatTimes;animation.fillMode = kCAFillModeForwards;return animation;}#pragma mark ====== 路径动画 ======+ (CAKeyframeAnimation *)keyframeAnimation:(CGMutablePathRef)path durTimes:(CGFloat)time Rep:(CGFloat)repeatTimes{CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"position"];animation.path = path;animation.removedOnCompletion = NO;animation.fillMode = kCAFillModeForwards;animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];//是否自动倒退animation.autoreverses = NO;animation.duration = time;animation.repeatCount = repeatTimes;return animation;}#pragma mark ====== 旋转动画 ======+ (CABasicAnimation *)rotation:(CGFloat)time degree:(CGFloat)degree direction:(CGFloat)direction repeatCount:(CGFloat)repeatCount{CATransform3D rotationTransform = CATransform3DMakeRotation(degree, 0, 0, direction);CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform"];animation.toValue = [NSValue valueWithCATransform3D:rotationTransform];animation.duration = time;//是否自动倒退animation.autoreverses = NO;animation.cumulative = NO;animation.fillMode = kCAFillModeForwards;animation.repeatCount = repeatCount;animation.delegate = self;return animation;}#pragma mark ====== 粒子动画 ======+ (CAEmitterLayer *)AnimationEmitterPosition:(CGPoint)emitterPosition{CAEmitterLayer *fireworksEmitter = [CAEmitterLayer layer];//发射位置fireworksEmitter.emitterPosition = emitterPosition;//发射源的z坐标位置fireworksEmitter.emitterZPosition = -20.f;//发射源的大小fireworksEmitter.emitterSize= CGSizeMake(10.f, 10.f);//决定粒子形状的深度联系//fireworksEmitter.emitterDepth = 30.f;//发射模式fireworksEmitter.emitterMode= kCAEmitterLayerOutline;//发射源的形状fireworksEmitter.emitterShape= kCAEmitterLayerLine;//渲染模式fireworksEmitter.renderMode= kCAEmitterLayerAdditive;//用于初始化随机数产生的种子 (1 -- 10)//fireworksEmitter.seed = (arc4random()%10)+1;//自旋转速度fireworksEmitter.spin = 0.f;//粒子的缩放比例fireworksEmitter.scale = 1.f;//粒子速度fireworksEmitter.velocity = 1.f;// Create the rocketCAEmitterCell *rocket = [CAEmitterCell emitterCell];rocket.birthRate= 5.0;//周围发射角度rocket.emissionRange= M_PI/6; // some variation in anglerocket.velocity= 300;//粒子的速度范围//rocket.velocityRange= 400;//粒子y方向的加速度分量rocket.yAcceleration= 275;rocket.lifetime= 1.02;// we cannot set the birthrate < 1.0 for the burstNSString *imageName = [NSString stringWithFormat:@"liveRoom_zan_da_%zd", getRandomNumber(1, 12)];rocket.contents= (id) [[UIImage imageNamed:imageName] CGImage];rocket.scale= 0.3;//rocket.color = [[UIColor redColor] CGColor];//rocket.greenRange = 1.0; // different colors//rocket.redRange = 1.0;//rocket.blueRange = 1.0;rocket.spinRange= M_PI/2;// slow spinrocket.alphaRange = 1.0;// the burst object cannot be seen, but will spawn the sparks// we change the color here, since the sparks inherit its valueCAEmitterCell *burst = [CAEmitterCell emitterCell];burst.birthRate= 1.0;// at the end of travelburst.velocity= 0;//burst.scale = 2.5;//粒子 red 在生命周期内的改变速度//burst.redSpeed = -1.5;//burst.blueSpeed = +1.5;//burst.greenSpeed= +1.0;burst.lifetime= 1.35;burst.alphaSpeed = -2.3;// putting it together//fireworksEmitter.emitterCells= [NSArray arrayWithObject:rocket];//rocket.emitterCells= [NSArray arrayWithObject:burst];return fireworksEmitter;}#pragma mark - UIView的,翻转、旋转、偏移、翻页、缩放、取反的动画效果 -//翻转- (void)animationFlipWithView:(UIView *)animationView{[UIView beginAnimations:@"doflip" context:nil];[UIView setAnimationDuration:1];//设置动画淡入淡出[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];[UIView setAnimationDelegate:self];//设置翻转方向[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:animationView cache:YES];[UIView commitAnimations];}//旋转- (void)animationRotateWithView:(UIView *)animationView{//创建一个CGAffineTransform transform对象CGAffineTransform transform;//设置旋转度数transform = CGAffineTransformRotate(animationView.transform, M_PI/6.0);[UIView beginAnimations:@"rotate" context:nil ];[UIView setAnimationDuration:2];[UIView setAnimationDelegate:self];//获取transform的值[animationView setTransform:transform];[UIView commitAnimations];}//偏移-(void)animationMoveWithView:(UIView *)animationView{[UIView beginAnimations:@"move" context:nil];[UIView setAnimationDuration:2];[UIView setAnimationDelegate:self];//改变它的frame的x,y的值animationView.frame = CGRectMake(100, 100, 120, 100);[UIView commitAnimations];}//翻页-(void)animationCurlUpWithView:(UIView *)animationView{[UIView beginAnimations:@"curlUp" context:nil];[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];//指定动画曲线类型,该枚举是默认的,线性的是匀速的[UIView setAnimationDuration:1];[UIView setAnimationDelegate:self];//设置翻页的方向[UIView setAnimationTransition:UIViewAnimationTransitionCurlUp forView:animationView cache:YES];[UIView commitAnimations];}//缩放-(void)animationScaleWithView:(UIView *)animationView{CGAffineTransform transform;transform = CGAffineTransformScale(animationView.transform, 1.2, 1.2);[UIView beginAnimations:@"scale" context:nil];[UIView setAnimationDuration:2];[UIView setAnimationDelegate:self];[animationView setTransform:transform];[UIView commitAnimations];}//取反的动画效果是根据当前的动画取他的相反的动画-(void)animationInvertWithView:(UIView *)animationView{CGAffineTransform transform;transform=CGAffineTransformInvert(animationView.transform);[UIView beginAnimations:@"Invert" context:nil];[UIView setAnimationDuration:2];[UIView setAnimationDelegate:self];//获取改变后的view的transform[animationView setTransform:transform];[UIView commitAnimations];}@end

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。