标签:
IOS 动画主要是指Core Animation框架。官方使用文档地址为:Core Animation Guide。
Core Animation是IOS和OS X平台上负责图形渲染与动画的基础框架。Core Animation可以作用与动画视图或者其他可视元素,为你完成了动画所需的大部分绘帧工作。你只需要配置少量的动画参数(如开始点的位置和结束点的位置)即可使用Core Animation的动画效果。Core Animation将大部分实际的绘图任务交给了图形硬件来处理,图形硬件会加速图形渲染的速度。这种自动化的图形加速技术让动画拥有更高的帧率并且显示效果更加平滑,不会加重CPU的负担而影响程序的运行速度。
Core Animation类的继承关系图
常用属性 duration : 动画的持续时间 beginTime : 动画的开始时间 repeatCount : 动画的重复次数 autoreverses : 执行的动画按照原动画返回执行 timingFunction : 控制动画的显示节奏系统提供五种值选择,分别是:
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 : 过渡动画的动画类型,系统提供了四种过渡动画。
_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 beginAnimations:@"move" context:nil]; [UIView setAnimationDuration:2]; [UIView setAnimationDelegate:self]; //改变它的frame的x,y的值 animationView.frame = CGRectMake(100, 100, 120, 100); [UIView commitAnimations];
<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];
位移动画代码演示:
//使用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"];
重要属性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
重要属性 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"];
CAAnimation的子类,用于做过渡动画或者转场动画,能够为层提供移出屏幕和移入屏幕的动画效果。 重要属性 type:动画过渡类型
Apple 官方的SDK其实只提供了四种过渡效果。
subtype:动画过渡方向
startProgress:动画起点(在整体动画的百分比) endProgress:动画终点(在整体动画的百分比)
效果演示://
// AnimationManager.h
// redlips
//
// Created by zizp on 15/12/23.
// Copyright ? 2015年 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 ? 2015年 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 rocket CAEmitterCell *rocket = [CAEmitterCell emitterCell]; rocket.birthRate = 5.0; //周围发射角度 rocket.emissionRange = M_PI/6; // some variation in angle rocket.velocity = 300; //粒子的速度范围 //rocket.velocityRange = 400; //粒子y方向的加速度分量 rocket.yAcceleration = 275; rocket.lifetime = 1.02; // we cannot set the birthrate < 1.0 for the burst NSString *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 spin rocket.alphaRange = 1.0; // the burst object cannot be seen, but will spawn the sparks // we change the color here, since the sparks inherit its value CAEmitterCell *burst = [CAEmitterCell emitterCell]; burst.birthRate = 1.0; // at the end of travel burst.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
标签:
原文地址:http://blog.csdn.net/u010092035/article/details/51888771