摘要

显式动画

属性动画

  1. CABasicAnimation *animation = [CABasicAnimation animation];
  2.         [self updateHandsAnimated:NO];
  3.         animation.keyPath = @"transform";
  4.         animation.toValue = [NSValue valueWithCATransform3D:transform];
  5.         animation.duration = 0.5;
  6.         animation.delegate = self;
  7.         [animation setValue:handView forKey:@"handView"];

关键帧动画

CAKeyframeAnimation是另一种UIKit没有暴露出来但功能强大的类。和CABasicAnimation类似,CAKeyframeAnimation同样是CAPropertyAnimation的一个子类,它依然作用于单一的一个属性,但是和CABasicAnimation不一样的是,它不限制于设置一个起始和结束的值,而是可以根据一连串随意的值来做动画。

关键帧起源于传动动画,意思是指主导的动画在显著改变发生时重绘当前帧(也就是关键帧),每帧之间剩下的绘制(可以通过关键帧推算出)将由熟练的艺术家来完成。CAKeyframeAnimation也是同样的道理:你提供了显著的帧,然后Core Animation在每帧之间进行插入。

  1. - (IBAction)changeColor
  2. {
  3.     //create a keyframe animation
  4.     CAKeyframeAnimation *animation = [CAKeyframeAnimation animation];
  5.     animation.keyPath = @"backgroundColor";
  6.     animation.duration = 2.0;
  7.     animation.values = @[
  8.                          (__bridge id)[UIColor blueColor].CGColor,
  9.                          (__bridge id)[UIColor redColor].CGColor,
  10.                          (__bridge id)[UIColor greenColor].CGColor,
  11.                          (__bridge id)[UIColor blueColor].CGColor ];
  12.     //apply animation to layer
  13.     [self.colorLayer addAnimation:animation forKey:nil];
  14. }

动画组

CABasicAnimation和CAKeyframeAnimation仅仅作用于单独的属性,而CAAnimationGroup可以把这些动画组合在一起。CAAnimationGroup是另一个继承于CAAnimation的子类,它添加了一个animations数组的属性,用来组合别的动画。

  1. - (void)viewDidLoad
  2. {
  3.     [super viewDidLoad];
  4.     //create a path
  5.     UIBezierPath *bezierPath = [[UIBezierPath alloc] init];
  6.     [bezierPath moveToPoint:CGPointMake(0, 150)];
  7.     [bezierPath addCurveToPoint:CGPointMake(300, 150) controlPoint1:CGPointMake(75, 0) controlPoint2:CGPointMake(225, 300)];
  8.     //draw the path using a CAShapeLayer
  9.     CAShapeLayer *pathLayer = [CAShapeLayer layer];
  10.     pathLayer.path = bezierPath.CGPath;
  11.     pathLayer.fillColor = [UIColor clearColor].CGColor;
  12.     pathLayer.strokeColor = [UIColor redColor].CGColor;
  13.     pathLayer.lineWidth = 3.0f;
  14.     [self.containerView.layer addSublayer:pathLayer];
  15.     //add a colored layer
  16.     CALayer *colorLayer = [CALayer layer];
  17.     colorLayer.frame = CGRectMake(0, 0, 64, 64);
  18.     colorLayer.position = CGPointMake(0, 150);
  19.     colorLayer.backgroundColor = [UIColor greenColor].CGColor;
  20.     [self.containerView.layer addSublayer:colorLayer];
  21.     //create the position animation
  22.     CAKeyframeAnimation *animation1 = [CAKeyframeAnimation animation];
  23.     animation1.keyPath = @"position";
  24.     animation1.path = bezierPath.CGPath;
  25.     animation1.rotationMode = kCAAnimationRotateAuto;
  26.     //create the color animation
  27.     CABasicAnimation *animation2 = [CABasicAnimation animation];
  28.     animation2.keyPath = @"backgroundColor";
  29.     animation2.toValue = (__bridge id)[UIColor redColor].CGColor;
  30.     //create group animation
  31.     CAAnimationGroup *groupAnimation = [CAAnimationGroup animation];
  32.     groupAnimation.animations = @[animation1, animation2]; 
  33.     groupAnimation.duration = 4.0;
  34.     //add the animation to the color layer
  35.     [colorLayer addAnimation:groupAnimation forKey:nil];
  36. }

过渡

有时候对于iOS应用程序来说,希望能通过属性动画来对比较难做动画的布局进行一些改变。比如交换一段文本和图片,或者用一段网格视图来替换,等等。属性动画只对图层的可动画属性起作用,所以如果要改变一个不能动画的属性(比如图片),或者从层级关系中添加或者移除图层,属性动画将不起作用。

于是就有了过渡的概念。过渡并不像属性动画那样平滑地在两个值之间做动画,而是影响到整个图层的变化。过渡动画首    先展示之前的图层外观,然后通过一个交换过渡到新的外观。

为了创建一个过渡动画,我们将使用CATransition,同样是另一个CAAnimation的子类,和别的子类不同,CATransition有一个type和subtype来标识变换效果。type属性是一个NSString类型,可以被设置成如下类型:

  1. kCATransitionFade 
  2. kCATransitionMoveIn 
  3. kCATransitionPush 
  4. kCATransitionReveal

到目前为止你只能使用上述四种类型,但你可以通过一些别的方法来自定义过渡效果,默认的过渡类型是kCATransitionFade,当你在改变图层属性之后,就创建了一个平滑的淡入淡出效果。kCATransitionPush,它创建了一个新的图层,从边缘的一侧滑动进来,把旧图层从另一侧推出去的效果。

kCATransitionMoveIn和kCATransitionReveal与kCATransitionPush类似,都实现了一个定向滑动的动画,但是有一些细微的不同,kCATransitionMoveIn从顶部滑动进入,但不像推送动画那样把老土层推走,然而kCATransitionReveal把原始的图层滑动出去来显示新的外观,而不是把新的图层滑动进入。

后面三种过渡类型都有一个默认的动画方向,它们都从左侧滑入,但是你可以通过subtype来控制它们的方向,提供了如下四种类型:

kCATransitionFromRight

kCATransitionFromLeft

kCATransitionFromTop

kCATransitionFromBottom

  1. @interface ViewController ()
  2. @property (nonatomic, weak) IBOutlet UIImageView *imageView;
  3. @property (nonatomic, copy) NSArray *images;
  4. @end
  5. @implementation ViewController
  6. - (void)viewDidLoad
  7. {
  8.     [super viewDidLoad];
  9.     //set up images
  10.     self.images = @[[UIImage imageNamed:@"Anchor.png"],
  11.                     [UIImage imageNamed:@"Cone.png"],
  12.                     [UIImage imageNamed:@"Igloo.png"],
  13.                     [UIImage imageNamed:@"Spaceship.png"]];
  14. }
  15. - (IBAction)switchImage
  16. {
  17.     //set up crossfade transition
  18.     CATransition *transition = [CATransition animation];
  19.     transition.type = kCATransitionFade;
  20.     //apply transition to imageview backing layer
  21.     [self.imageView.layer addAnimation:transition forKey:nil];
  22.     //cycle to next image
  23.     UIImage *currentImage = self.imageView.image;
  24.     NSUInteger index = [self.images indexOfObject:currentImage];
  25.     index = (index + 1) % [self.images count];
  26.     self.imageView.image = self.images[index];
  27. }
  28. @end

你可以从代码中看出,过渡动画和之前的属性动画或者动画组添加到图层上的方式一致,都是通过-addAnimation:forKey:方法。但是和属性动画不同的是,对指定的图层一次只能使用一次CATransition,因此,无论你对动画的键设置什么值,过渡动画都会对它的键设置成“transition”,也就是常量kCATransition。

自定义动画

苹果通过UIView +transitionFromView:toView:duration:options:completion:和+transitionWithView:duration:options:animations:方法提供了Core Animation的过渡特性。但是这里的可用的过渡选项和CATransition的type属性提供的常量完全不同。UIView过渡方法中options参数可以由如下常量指定:

UIViewAnimationOptionTransitionFlipFromLeft

使用UIKit提供的方法来做过渡动画

  1. @interface ViewController ()
  2. @property (nonatomic, weak) IBOutlet UIImageView *imageView;
  3. @property (nonatomic, copy) NSArray *images;
  4. @end
  5. @implementation ViewController
  6. - (void)viewDidLoad
  7. {
  8.     [super viewDidLoad]; //set up images
  9.     self.images = @[[UIImage imageNamed:@"Anchor.png"],
  10.                     [UIImage imageNamed:@"Cone.png"],
  11.                     [UIImage imageNamed:@"Igloo.png"],
  12.                     [UIImage imageNamed:@"Spaceship.png"]];
  13. - (IBAction)switchImage
  14. {
  15.     [UIView transitionWithView:self.imageView duration:1.0
  16.                        options:UIViewAnimationOptionTransitionFlipFromLeft
  17.                     animations:^{
  18.                         //cycle to next image
  19.                         UIImage *currentImage = self.imageView.image;
  20.                         NSUInteger index = [self.images indexOfObject:currentImage];
  21.                         index = (index + 1) % [self.images count];
  22.                         self.imageView.image = self.images[index];
  23.                     }
  24.                     completion:NULL];
  25. }
  26. @end

iOS 动画基础-显式动画的更多相关文章

  1. CoreAnimation4-隐式动画和显式动画

    事务 Core Animation基于一个假设,说屏幕上的任何东西都可以(或者可能)做动画.动画并不需要你在Core Animation中手动打开,相反需要明确地关闭,否则他会一直存在. 当你改变CA ...

  2. CALayer的隐式动画和显式动画

    隐式事务 任何对于CALayer属性的修改,都是隐式事务,都会有动画效果.这样的事务会在run-loop中被提交. - (void)viewDidLoad { //初始化一个layer,添加到主视图 ...

  3. [iOS Animation]-CALayer 隐式动画

    隐式动画 按照我的意思去做,而不是我说的. -- 埃德娜,辛普森 我们在第一部分讨论了Core Animation除了动画之外可以做到的任何事情.但是动画是Core Animation库一个非常显著的 ...

  4. iOS:CALayer的隐式动画的详解

    CALayer的隐式动画属性: •每一个UIView内部都默认关联着一个CALayer,称这个Layer为Root Layer.所有的非Root Layer都存在着隐式动画,隐式动画的默认时长为1/4 ...

  5. iOS中的隐式动画

    隐式动画就是指  在 非 人为在代码中 定义动画  而系统却默认  自带   的动画  叫做隐式动画. 比如  改变 图层  的颜色  位置  和   透明度  的时候    都会  产生附带的渐变的 ...

  6. iOS动画学习 -隐式动画

    事务 Core Animation基于一个假设,说屏幕上的任何东西都可以(或者可能)做动画.你并不需要在Core Animation中手动打开动画,但是你需要明确地关闭它,否则它会一直存在. 当你改变 ...

  7. android 动画基础绘——view 动画(二)[补]

    前言 这个是对view 动画的补充,是一些view 动画的特殊使用场景. 回顾第一篇关于view 动画的,我介绍到view的动画都是针对元素本身的. 当我们开发view动画的时候,我们看到几个元素在做 ...

  8. android 动画基础绘——view 动画

    前言 对android 动画的整理,android 动画分为view动画(也叫补间动画),帧动画,属性动画. 看到这几个概念,让我想起了flash这东西.如果需要查各种动画具体的含义,那么可以去查询f ...

  9. android 动画基础绘——帧动画(三)

    前言 这篇介绍帧动画. 什么是帧动画? 帧动画,非常好理解.就是轮播,比如我们看电视,其实就是一张一张播放过去的. 正文 <?xml version="1.0" encodi ...

随机推荐

  1. 一个Redis实例适合存储不同应用程序的数据吗?

    Redis支持多个数据库,并且每个数据库的数据是隔离的不能共享,并且基于单机才有,如果是集群就没有数据库的概念. Redis是一个字典结构的存储服务器,而实际上一个Redis实例提供了多个用来存储数据 ...

  2. 【转】Python常见web系统返回码

    responses = { 100: ('Continue', 'Request received, please continue'), 101: ('Switching Protocols', ' ...

  3. Python3基础 全局变量 在函数内可使用,不可直接修改

             Python : 3.7.3          OS : Ubuntu 18.04.2 LTS         IDE : pycharm-community-2019.1.3    ...

  4. WPF窗体自适应分辨率

    使用WPF创建一个窗体(Window)时,如果设置了固定的高度(Height)和宽度(Width),一旦用户的电脑分辨率过低,就会使得窗体及其中的内容无法完整地显示出来.要解决这个这个问题,有以下几个 ...

  5. Spring Cloud 如何使用Eureka注册服务 4.2.2

    要使用Eureka实现服务发现,需要项目中包含Eureka的服务端发现组件以及客户端发现组件. 搭建Maven父工程 创建一个Maven父工程xcservice-springcloud,并在工程的po ...

  6. HTTPS小结 、TSL、SSL

    https://segmentfault.com/a/1190000009020635

  7. Winsock.简单UDP

    PS:vs2017 编译C++代码 支持 XP:项目属性-->链接器-->系统-->需要的最小版本--> 输入 "5.1" 1.ZC:测试:c向s 发送长度 ...

  8. JDK线程池框架Executor源码阅读

    Executor框架 Executor ExecutorService AbstractExecutorService ThreadPoolExecutor ThreadPoolExecutor继承A ...

  9. [bzoj5483][Usaco2018 Dec]Balance Beam_凸包_概率期望

    bzoj5483 Usaco2018Dec Balance Beam 题目链接:https://lydsy.com/JudgeOnline/problem.php?id=5483 数据范围:略. 题解 ...

  10. 解决 IE 或者兼容模式不支持 document.getElementsByClassName() 的方法

    网页错误详细信息消息: 对象不支持此属性或方法 document.getElementsByClassName('element_name') 需要自己实现下该方法,因为ie5之前的版本并不支持这个方 ...