Core Animation 基本动画效果汇总

前几篇文章中,我详细的说明了Core Animation相关的理论知识。这一节,我将举例说明基本动画的使用。

一、 CABasicAnimation

首先我创建一个用于实现动画的图层,代码如下:

  1. - (void)viewDidLoad {  
  2.     [super viewDidLoad];  
  3.     CALayer *layer = [CALayer layer];  
  4.     layer.position = CGPointMake(100100);  
  5.     layer.bounds = CGRectMake(00100100);  
  6.     layer.backgroundColor = [UIColor redColor].CGColor;  
  7.     [self.view.layer addSublayer:layer];  
  8.     self.layer = layer;  
  9. }  

1. 透明度变化

动画代码如下:

  1. CABasicAnimation *fadeAnimation = [CABasicAnimation animationWithKeyPath:@"opacity"];  
  2. // 动画起始值  
  3. fadeAnimation.fromValue = @(1.0);  
  4. // 动画结束值  
  5. fadeAnimation.toValue = @(0.0);  
  6. // 动画持续时间  
  7. fadeAnimation.duration = 2.0;  
  8. // key 动画标识  
  9. [self.layer addAnimation:fadeAnimation forKey:@"opacityAnimation"];  


动画效果如下:

可以看出,动画是按照设想的执行,但是在动画结束后,又返回原来的状态了。

原因分析:注意到,本例中,我使用的显式动画,不同于隐式动画,隐式动画会更新图层对象的值。而显式动画不会更改图层树中的数据。显式动画仅是创建了一个动画。在动画结束之后,Core Animation从图层中移除该动画对象并使用当前的数据值重绘图层。(所以显式动画会出现动画结束后,突然回到原始位置的情况)。

解决方案:

I.   更新赋值图层属性

这种方案的原理就是动画开始的时候,就确定图层的最终值;这样操作的话,当动画结束并且被移除后,显示的是图层树中的值。代码如下:

  1. CABasicAnimation *fadeAnimation = [CABasicAnimation animationWithKeyPath:@"opacity"];  
  2. // 动画起始值  
  3. fadeAnimation.fromValue = @(1.0);  
  4. // 动画结束值  
  5. fadeAnimation.toValue = @(0.0);  
  6. // 动画持续时间  
  7. fadeAnimation.duration = 3.0;  
  8. /*一开始就确定动画结束后,图层最终的透明值*/  
  9. self.layer.opacity = 0;  
  10. // key 动画标识  
  11. [self.layer addAnimation:fadeAnimation forKey:@"opacityAnimation"];  

II.  不移除动画,并填充

  1. CABasicAnimation *fadeAnimation = [CABasicAnimation animationWithKeyPath:@"opacity"];  
  2. // 动画起始值  
  3. fadeAnimation.fromValue = @(1.0);  
  4. // 动画结束值  
  5. fadeAnimation.toValue = @(0.0);  
  6. // 动画持续时间  
  7. fadeAnimation.duration = 3.0;  
  8. /* 动画执行完毕后不要删除动画 */  
  9. fadeAnimation.removedOnCompletion = NO;  
  10. /* 保持最新的状态 */  
  11. fadeAnimation.fillMode = kCAFillModeForwards;  
  12. // key 动画标识  
  13. [self.layer addAnimation:fadeAnimation forKey:@"opacityAnimation"];</span>  
这样操作的话,动画并没有被移除掉,而是会一直驻留在内存中,所以应该在控制器销毁的时候,应该也将动画移除掉(根据动画标识)。

  1. - (void)dealloc {  
  2.     [self.layer removeAnimationForKey:@"opacityAnimation"];  
  3. }  

有人会问,为什么不使用UIView的block操作来实现此功能呢?因为这一节中,我是主要讲解Core Animation相关的图层动画,解释其执行过程及原理;大家在明白这里过程及原理后,适用UIView的block操作(它的内部实现就是借助图层动画,只是进行了一层封装)来实现动画,也是极好的。

2. 平移动画

动画代码如下:

  1. // 1.创建动画对象  
  2. CABasicAnimation *anim = [CABasicAnimation animation];  
  3.   
  4. // 2.设置动画对象  
  5. // keyPath决定了执行怎样的动画, 调整哪个属性来执行动画  
  6. anim.keyPath = @"position";  
  7. //    anim.fromValue = [NSValue valueWithCGPoint:CGPointMake(0, 0)];  
  8. // toValue : 最终变成什么值  
  9. // byValue : 增加多少值  
  10. anim.byValue = [NSValue valueWithCGPoint:CGPointMake(200200)];  
  11. anim.duration = 2.0;  
  12.   
  13. /**让图层保持动画执行完毕后的状态**/  
  14. // 动画执行完毕后不要删除动画  
  15. anim.removedOnCompletion = NO;  
  16. // 保持最新的状态(动画结束后的状态)  
  17. anim.fillMode = kCAFillModeForwards;  
  18.   
  19. // 3.添加动画  
  20. [self.layer addAnimation:anim forKey:nil];  

动画效果如下:



3. 缩放动画

动画代码如下:

  1. // 1.创建动画对象  
  2.     CABasicAnimation *anim = [CABasicAnimation animation];  
  3.       
  4.     // 2.设置动画对象  
  5.     // keyPath决定了执行怎样的动画, 调整哪个属性来执行动画  
  6.     anim.keyPath = @"bounds";  
  7.     //    anim.fromValue = [NSValue valueWithCGPoint:CGPointMake(0, 0)];  
  8.     anim.toValue = [NSValue valueWithCGRect:CGRectMake(00200200)];  
  9.     anim.duration = 2.0;  
  10.       
  11.     /**让图层保持动画执行完毕后的状态**/  
  12.     // 动画执行完毕后不要删除动画  
  13.     anim.removedOnCompletion = NO;  
  14.     // 保持最新的状态  
  15.     anim.fillMode = kCAFillModeForwards;  
  16.       
  17.     // 3.添加动画  
  18.     [self.layer addAnimation:anim forKey:nil];  

动画效果如下:


4. 旋转动画

动画代码如下:

  1. // 1.创建动画对象  
  2.     CABasicAnimation *anim = [CABasicAnimation animation];  
  3.       
  4.     // 2.设置动画对象  
  5.     // keyPath决定了执行怎样的动画, 调整哪个属性来执行动画  
  6.     anim.keyPath = @"transform";  
  7.     //    anim.fromValue = [NSValue valueWithCGPoint:CGPointMake(0, 0)];  
  8.     anim.toValue = [NSValue valueWithCATransform3D:CATransform3DMakeRotation(M_PI, 1, -10)];  
  9.       
  10.     anim.duration = 2.0;  
  11.       
  12.     anim.removedOnCompletion = NO;  
  13.     anim.fillMode = kCAFillModeForwards;  
  14.       
  15.     // 3.添加动画  
  16.     [self.layer addAnimation:anim forKey:nil];  

动画效果如下:




二、CAKeyframeAnimation

1. 连续动画

动画代码如下:

  1. //CABasicAnimation  fromValue --> toValue  
  2.     CAKeyframeAnimation *anim = [CAKeyframeAnimation animation];  
  3.       
  4.     anim.keyPath = @"position";  
  5.       
  6.     NSValue *v1 = [NSValue valueWithCGPoint:CGPointZero];  
  7.     NSValue *v2 = [NSValue valueWithCGPoint:CGPointMake(100100)];  
  8.     NSValue *v3 = [NSValue valueWithCGPoint:CGPointMake(100200)];  
  9.     NSValue *v4 = [NSValue valueWithCGPoint:CGPointMake(250250)];  
  10.     anim.values = @[v1, v2, v3, v4];  
  11.       
  12.     anim.duration = 2.0;  
  13.       
  14.     anim.removedOnCompletion = NO;  
  15.     // 保持最新的状态  
  16.     anim.fillMode = kCAFillModeForwards;  
  17.       
  18.     [self.redView.layer addAnimation:anim forKey:nil];  

动画效果如下:


2. 缓冲动画

动画代码如下:

  1. CAKeyframeAnimation *anim = [CAKeyframeAnimation animation];  
  2.       
  3.     anim.keyPath = @"position";  
  4.     anim.removedOnCompletion = NO;  
  5.     anim.fillMode = kCAFillModeForwards;  
  6.     anim.duration = 4.0;  
  7.       
  8.     CGMutablePathRef path = CGPathCreateMutable();  
  9.     CGPathAddEllipseInRect(path, NULL, CGRectMake(100100200200));  
  10.     anim.path = path;  
  11.     CGPathRelease(path);  
  12.       
  13.     // 设置动画的执行节奏  
  14.     // kCAMediaTimingFunctionEaseInEaseOut : 一开始比较慢, 中间会加速,  临近结束的时候, 会变慢  
  15.     anim.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];  
  16.     anim.delegate = self;  
  17.       
  18.     [self.redView.layer addAnimation:anim forKey:nil];  

动画效果如下:



注意到:代码中也可以对动画设置代理,用来监听动画的执行动作。比如下面代码:

  1. #pragma mark - 动画的代理方法  
  2. #pragma mark 动画开始的时候调用  
  3. - (void)animationDidStart:(CAAnimation *)anim  
  4. {  
  5.     NSLog(@"animationDidStart");  
  6. }  
  7. #pragma mark 动画结束的时候调用  
  8. - (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag  
  9. {  
  10.     NSLog(@"animationDidStop");  
  11. }  

3. 抖动效果

动画代码如下:

  1. - (void)viewDidLoad  
  2. {  
  3.     [super viewDidLoad];  
  4.       
  5.     self.myImage.layer.cornerRadius = 15;  
  6.     self.myImage.layer.masksToBounds = YES;  
  7.       
  8. }  
  9.   
  10. - (IBAction)start {  
  11.       
  12.     CAKeyframeAnimation *anim = [CAKeyframeAnimation animation];  
  13.     anim.keyPath = @"transform.rotation";  
  14.       
  15.     anim.values = @[@(Angle(-5)),@(Angle(5)),@(Angle(-5))];  
  16.       
  17.     anim.repeatCount = 10;  
  18.       
  19.     anim.duration = 0.3;  
  20.       
  21.     [self.myImage.layer addAnimation:anim forKey:@"Shake"];  
  22.       
  23. }  
  24.   
  25. - (IBAction)stop {  
  26.     [self.myImage.layer removeAnimationForKey:@"Shake"];  
  27. }  

动画效果如下:


三、 CATransition

动画代码如下:

  1. - (IBAction)prev {  
  2.       
  3.     self.index--;  
  4.       
  5.     if(self.index == -1){  
  6.         self.index = 8;  
  7.     }  
  8.   
  9.       
  10.     UIImage *prevImage = [UIImage imageNamed:[NSString stringWithFormat:@"%d.jpg",self.index+1]];  
  11.       
  12.     self.myImage.image = prevImage;  
  13.       
  14.     CATransition *anim = [CATransition animation];  
  15.     anim.type = @"pageUnCurl";  
  16.     anim.subtype = @"kCATransitionFromLeft";  
  17.       
  18.     [self.myImage.layer addAnimation:anim forKey:nil];  
  19.       
  20. }  
  21.   
  22. - (IBAction)next {  
  23.       
  24.     self.index++;  
  25.       
  26.     if(self.index == 9){  
  27.         self.index = 0;  
  28.     }  
  29.       
  30.     UIImage *nextImage = [UIImage imageNamed:[NSString stringWithFormat:@"%d.jpg",self.index+1]];  
  31.       
  32.     self.myImage.image = nextImage;  
  33.       
  34.     CATransition *anim = [CATransition animation];  
  35.     anim.type = @"pageCurl";  
  36.     anim.subtype = @"kCATransitionFromRight";  
  37.       
  38.     [self.myImage.layer addAnimation:anim forKey:nil];  
  39. }  

动画效果如下:



对代码中得type及subtype 进行说明(大家可以自己尝试看看效果):

type:

     pageCurl               向上翻一页 
     pageUnCurl          向下翻一页 
     rippleEffect           滴水效果 
     suckEffect             收缩效果,如一块布被抽走 
     cube                      立方体效果 
     oglFlip                  上下翻转效果

subtype:

     kCATransitionFade        交叉淡化过渡 
     kCATransitionMoveIn   新视图移到旧视图上面 
     kCATransitionPush        新视图把旧视图推出去 
     kCATransitionReveal     将旧视图移开,显示下面的新视图 


四、 CAAnimationGroup

动画代码如下:

  1. // 1.创建旋转动画对象  
  2.         CABasicAnimation *rotate = [CABasicAnimation animation];  
  3.         rotate.keyPath = @"transform.rotation";  
  4.         rotate.toValue = @(M_PI);  
  5.           
  6.         // 2.创建缩放动画对象  
  7.         CABasicAnimation *scale = [CABasicAnimation animation];  
  8.         scale.keyPath = @"transform.scale";  
  9.         scale.toValue = @(0.0);  
  10.           
  11.         // 3.平移动画  
  12.         CABasicAnimation *move = [CABasicAnimation animation];  
  13.         move.keyPath = @"transform.translation";  
  14.         move.toValue = [NSValue valueWithCGPoint:CGPointMake(100100)];  
  15.           
  16.         // 4.将所有的动画添加到动画组中  
  17.         CAAnimationGroup *group = [CAAnimationGroup animation];  
  18.         group.animations = @[rotate, scale, move];  
  19.         group.duration = 5.0;  
  20.         group.removedOnCompletion = NO;  
  21.         group.fillMode = kCAFillModeForwards;  
  22.           
  23.         [self.iconView.layer addAnimation:group forKey:nil];  

动画效果如下:



总结:在本章节中,对Core Animation中所涉及的相关动画(平移,缩放,旋转,组合)进行了举例说明。在后面的几个章节中,我将逐步介绍动画的高级应用及应用案例。 To Be Continued...


转载自:http://blog.csdn.net/sinat_27706697/article/details/46864775

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值