Core Animation

主要内容

  1. Core Animation 简介
  2. CALayer
    1. CALayer 简介
    2. 层与视图的关系
    3. CALayer 的使用
    4. 层的显示内容
    5. 隐式可动画属性
    6. 层、位图与上下文
  3. CAAnimation
    1. CAAnimation 简介
    2. 通过CABasicAnimation 实现旋转动画
    3. 通过CAKeyframeAnimation 实现弹跳动画
    4. 外观层和模型层

 

Core Animation 简介

  • 动画重要性:在 iOS 里使用恰当的动画,能给予用户视觉线索,更好地了解应用的工作流程,提升用户体验。
  • 使用 Core Animation :QuartzCore.framework

        

  • Core Animation 两个主要的类是 CALayer 和 CAAnimation

 

CALayer

CALayer 简介

  • CALayer 实例本质是一块包含一幅位图(bitmap)的缓冲区。
  • 位图图像(bitmap),亦称为点阵图像或绘制图像,是由称作像素(图片元素)的单个点组成的。
  • 位图与矢量图的比较

 

层与视图的关系

创建视图实例时,视图会自己创建一个层(隐式层)。视图在绘图时,会将内容画在自己的层上。

  • 根据每个像素的不透明度(opacity),将一组层按照特定的顺序拷贝至屏幕。
  • 视图先在层上完成绘图,然后系统会将所有的层合成至屏幕。

 

为什么要将视图和层分成两个概念?

UIView是UIResponder的子类,是用类封装起来的一个抽象概念,用来描述某种“可视对象”。通过屏幕,这类对象可以和用户交互。

CALayer 只和绘图,内容显示有关。

 

CALayer 的使用

    显式层:通过 CALayer 类发送alloc 创建。

    对UIView,可以通过定义视图的frame属性,设置相应的大小和位置。frame 矩形的起始点(origin)是视图的左上角,再从起始点开始,根据大小向右和向下延伸。

    对CALayer,一般不是定义frame,而是设置bounds和position

    position的默认值是父层的center,anchorPoint 决定position在(层的)bounds中的位置,默认值(0.5,0.5),即中心点。如果值修改层的大小,不修改位置,层会保持居中显示。

    虽然没有frame,通过发送 frame 和 setFrame:存取frame。当层收到frame消息时,会通过position和bounds计算出相应的矩形区域。当层收到 setFrame:消息时,会执行若干数学运算,然后将相应的值赋给bounds和position

 

层的显示内容

    可以通过代码或 UIImage 设置层的contents属性。

    通过代码设置contents属性有两种方法(都要用到Core Graphics):

  1. 创建CALayer子类。可以根据层的某些状态绘制不同的内容。这种情况下只能选择覆盖 drawInContext:方法。
  2. 为CALayer实例设置委托对象,然后由委托对象实现绘图(隐式层使用的就是这种方法;视图是它的隐式层的委托对象)隐式层或显示层,都可以使用委托机制。不要将UIView对象设置为显示层的委托对象。这是因为UIview已经是隐式层的委托对象。显示层时,层会向它的委托对象发送 drawLayer:inContext:消息。委托对象可以通过传入的context对象,执行相应的 CoreGraphics调用

    QuartzCore框架(包含CALayer和CAAnimation)和Core Graphics (包含CGImageRef)都能在iOS和Mac OS X上使用,但是 UIKit(包含UIImage和其他所有UI开头的类)只能在iOS中使用。

    为了保持可移植性,QuartzCore不能使用UIImage,只能使用 CGImageRef。

    层是以层次结构的形式存在的,层可以有子层。每个层都有一个指针指回它的父层,这个指针称为superLayer。系统在将某个层合成至屏幕时,会先将这个层拷贝至屏幕,然后依次将其下子层合成在它的上面。任何一个层必定是在它的父层之上绘制的。

    在视图层次结构中,兄弟视图(有相同父视图的视图)的bounds属性通常不会重叠,没有意义,即使重叠,只会妨碍用户操作。

    层负责的是视觉效果和绘图,兄弟层很可能会重叠。

    如何决定兄弟层的合成顺序?层有一个 zPosition。如果两个层是兄弟层并且重叠,zPosition值高的层会在zPosition值低得层之上合成(子层必会在父层之上绘图,和zPosition无关)

 

隐式可动画属性

    部分CALayer属性是隐式可动画的。调用这些属性的存方法时,相应的修改会自动产生动画效果。position属性是隐式可动画属性。

    拖拽动画的不连贯区别说明:

    通过动画事务可以关闭隐式动画。动画事务可以批量处理动画并设置相应的参数。例如持续时间和动画曲线。

    向CATransaction 类发送 begin 消息可以开始一个动画事务。

    向CATransaction 类发送 commit 消息可以结束动画事务。

    在begin和commit之间,可以统一设置层的属性和CATransaction对象的属性。

 

层、位图与上下文

    层就是一副位图,一保存着每个像素的红、绿、蓝和alpha数值的内存空间。

    当UIView实例收到setNeedsDisplay消息后,会将该消息转发给视图的层。当运行循环处理完一个事件后,所有标记为“需要重新显示”的层都会准备一个CGContextRef。在调用绘图函数或绘图方法时,如果传入的上下文参数是CGContextRef,那么生成的像素最终都会体现在这个层的位图中。

- (void)drawRect:(CGRect)r
{
    CGContextRef ctx = UIGraphicsGetCurrentContext();
}

    就能得到一个CGContextRef指针,指向层的 CGContext 对象。在 drawRect:中完成的所有绘图都会填入层的位图,然后拷贝至屏幕。

    绘图函数或绘图方法所生成的像素最终会体现在层的位图中。

    UIGraphics系列函数提供了一套简便方案,可以创建位图CGContext对象,并将其写入UIImage对象。

    当层重画显示内容时,会创建相同类型的上下文对象。但实现方法稍有不同

    

CAAnimation

CAAnimation简介

    CAAnimation 对象可以在一定时间内持续引发某个数值的变化。通常会通过CAAnimation对象修改层的某个属性(例如,opacity)。

    CAAnimation是一组指令(例如,用2秒的时间,从A点移动到B点)

    可以将 动画对象(CAAnimation)加入CALayer实例,一旦加入,层就会开始执行动画对象的指令。

    CALayer 的很多属性都可以通过CAAnimation实现动画效果,这些属性包括:opacity、position、transform、bounds和contents等

    iOS 中的所有动画效果都是由CAAnimation驱动的。

    CAAnimation 是所有动画对象的抽象父类。它负责处理速度控制(timing),例如,CAAnimation的duration属性,通过这个属性可以设置动画的持续时间。由于 CAAnimation 是抽象类,所以不能直接使用。这里必需使用CAAnimation的某个具体子类。

    

    CAPropertyAnimation 是 CAAnimation 的子类,通过加入修改层属性的功能,扩充了父类,每个属性动画(property animation)都有一个类型为 NSString 的键路径(key path)。这个字符串是CALayer的可动画属性的属性名。CALayer的很多属性都支持动画效果。

    Apple的开发文档列出了完整的列表:查找 animatable properties

    建路径通常就是属性的名称。例如,拥有键路径 opacity 的动画属性,能够为层 opacity 属性实现动画效果。

    某些属性的类型是 C 结构(例如 position,类型是 CGPoint),通过键路径可以访问这些结构的所有成员,(详见开发文档 Core Animation Extensions To Key-Value Coding)。

    和 CAAnimation 一样,CAPropertyAnimation 也是抽象类。要创建能够修改某个层属性的动画对象,需要使用以下两个 CAPropertyAnimation 的具体子类(二选一):CABasicAnimation 和 CAKeyframeAnimation.使用 Core Animation时,会经常用到这两个类。

    CABasicAnimation 相对较简单,他有两个属性:fromValue和toValue,还有继承自CAAnimation的duration属性。将 CABasicAnimation加入层后,该对象的fromValue 会被赋值给需要动画的属性。随着动画的进行(持续时间通过duration设定),相应属性的值将线性地从 fromValue 变为 toValue。

    CABasicAnimation 和  CAKeyframeAnimation 的区别:CABasicAnimation 只能从一个数值变成另一个数值,而 CAKeyframeAnimation 没有这种限制。CAKeyframeAnimation 会使用 NSArray 对象保存这些数值,并以发生的顺序排列,且它的values属性负责保存这个数组。

    values 属性中的对象称为关键帧。动画对象会按指定的时间(duration)带着需要动画的属性,依次显示数组中的每一个关键帧。CABasicAnimation 对象其实是一个最多只能有两个关键帧的 CAKeyframeAnimation 对象(除了支持两个以上的关键帧,CAKeyframeAnimation还可以修改每个关键帧的速度,这里先不做介绍)

    另外还有两个 CAAnimation 子类,它们的使用频率相对较少。CAAnimationGroup 实例能够保存一组动画对象。将CAAnimationGroup加入层后,组中所有动画会同时并发运行。

    CATransition 能够为层提供移出屏幕和移入屏幕时的动画效果。在 Mac OS X上, CATransition 由功能强大的Core Image Filters 实现;在iOS上,它只能实现少量简单渐变效果,例如:渐隐渐现(fade)和滑入画出(sliding)(UINavigationController就是通过CATransition实现了将是同控制对象的视图推入屏幕时的动画效果)

 

通过CABasicAnimation 实现旋转动画

速度控制函数:CAMediaTimingFunction

动画结束后的处理:

有时需要知道某个动画会在何时结束,这样就可以在动画结束时执行特定的任务,例如,连续显示动画,或者在动画结束后更新某个对象。

每个动画对象可以有一个委托对象,动画对象会在动画结束时向委托对象发送 animationDidStop:finished:消息

 

通过CAKeyframeAnimation 实现弹跳动画

速度控制函数:CAMediaTimingFunction

 

外观层和模型层

    可以将CALayer实例想象为两部分:

  1. 合成至屏幕的图像内容
  2. 描述如何合成层一组参数:opacity、transform、position等

    实际上,对动画中的层,会有两套这样的参数:一套针对模型(model),另一套针对外观(presentation)。外观参数是动画对象持续平滑地修改的那些参数,而模型参数是不变的,即动画结束后真正生效的参数。

    对动画中的层,系统会使用外观参数将层的显示内容合成至屏幕。而在和动画无关的情况下,则会使用模型参数。

    以上两套参数的正式名称是模型层(the model layer)和外观层(the presentation layer)。

    向层查询 position 属性,得到的时模型层的position属性。要获取外观层的属性,需要先得到 presentationLayer 。

 

在什么情况下会用到外观层的属性?

    假设有一款游戏应用会在屏幕上显示动画的对象,当用户按中某个对象时,相应的对象就会爆炸。因为只有外观层才知道对象在屏幕上的当前位置,所以为了能对用户的按下动作做出精确的碰撞测试,就必须知道外观层的属性。

 

防止出现以下两种常见错误。:

  1. 动画效果表现正常。但是在动画结束后,层又回到了初始位置(或不透明度,等等),没能按预期保留状态。发生此类问题的原因是没有更新模型参数,并和动画的最终状态匹配。
  2. 层直接进入最终状态,没有动画效果。启动动画时,如果没有为 fromValue赋值,那么对象会自动地讲模型层的相应属性赋给fromValue。如果在动画开始前模型层更新至了最终状态,就会导致 fromVallue 和 toValue 是相同的值。一般情况下显式地为 fromValue 赋值即能修正此类问题。

 

 

转载于:https://my.oschina.net/u/859523/blog/906510

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值