简介
在iOS中,图形可分为以下几个层次:
越上层,封装程度越高,动画实现越简洁越简单,但是自由度越低;反之亦然。本文着重介绍Core Animation层的基本动画实现方案。
在iOS中,展示动画可以类比于显示生活中的“拍电影”。拍电影有三大要素:演员+剧本+开拍,概念类比如下:
1 | 演员--->CALayer,规定电影的主角是谁 |
概念
CALayer是什么呢?
CALayer
是个与UIView
很类似的概念,同样有layer,sublayer...
,同样有backgroundColor
、frame
等相似的属性,我们可以将UIView
看做一种特殊的CALayer
,只不过UIView
可以响应事件而已。一般来说,layer
可以有两种用途,二者不互相冲突:一是对view相关属性的设置,包括圆角、阴影、边框等参数;二是实现对view的动画操控。因此对一个view进行core animation动画
,本质上是对该view
的layer
进行动画操纵。
CAAnimation是什么呢?
CAAnimation可分为以下四种:
CABasicAnimation
通过设定起始点,终点,时间,动画会沿着你这设定点进行移动。可以看做特殊的CAKeyFrameAnimationCAAnimationGroup
Group也就是组合的意思,就是把对这个Layer的所有动画都组合起来。PS:一个layer设定了很多动画,他们都会同时执行,如何按顺序执行我到时候再讲。CATransition
这个就是苹果帮开发者封装好的一些动画CAKeyframeAnimation
Keyframe顾名思义就是关键点的frame,你可以通过设定CALayer的始点、中间关键点、终点的frame,时间,动画会沿你设定的轨迹进行移动
相关类
- CATransaction
事务类,可以对多个layer的属性同时进行修改.它分隐式事务,和显式事务
CABasicAnimation 单个动画
1 | override func viewDidLoad() { |
想要实现不同的效果,最关键的地方在于CABasicAnimation
对象的初始化方式中keyPath
的设定。
keyPath
在iOS中有以下几种不同的keyPath,代表着不同的效果:
1 | transform.scale = 比例转换 |
有用的属性设置
Autoreverses
当你设定这个属性为true
时,在它到达目的地之后,动画的返回到开始的值,代替了直接跳转到 开始的值。Duration
Duration
这个参数你已经相当熟悉了。它设定开始值到结束值花费的时间。期间会被速度的属性所影响。RemovedOnCompletion
这个属性默认为true
,那意味着,在指定的时间段完成后,动画就自动的从层上移除了。这个一般不用。假如你想要再次用这个动画时,你需要设定这个属性为false
。这样的话,下次你在通过-set 方法设定动画的属 性时,它将再次使用你的动画,而非默认的动画。Speed
默认的值为 1.0.这意味着动画播放按照默认的速度。如果你改变这个值为 2.0,动画会用 2 倍的速度播放。 这样的影响就是使持续时间减半。如果你指定的持续时间为 6 秒,速度为 2.0,动画就会播放 3 秒钟。BeginTime
这个属性在组动画中很有用。它根据父动画组的持续时间,指定了开始播放动画的时间。默认的是 0.0.组TimeOffset
如果一个时间偏移量是被设定,动画不会真正的可见,直到根据父动画组中的执行时间得到的时间都流逝了。RepeatCount
默认的是 0,意味着动画只会播放一次。如果指定一个无限大的重复次数,使用MAXFLOAT
。这个不应该和repeatDration
属性一块使用。RepeatDuration
这个属性指定了动画应该被重复多久。动画会一直重复,直到设定的时间流逝完。它不应该和repeatCount
一起使用。
CAAnimationGroup 组合动画
1 | func initGroupLayer() |
CATransition 苹果封装好的动画
先上代码
1 | weak var anImageView: UIImageView! |
上面代码中type
是动画效果,可选值如下:
1 | 1.#define定义的常量 |
subtype
:动画的方向,可选值如下:
1 | kCATransitionFromTop 从顶部开始 |
timingFunction
:过渡效果,可选值如下:
1 | kCAMediaTimingFunctionLinear//线性 |
CAKeyframeAnimation 关键帧动画
现在要实现下图的效果
具体代码如下
1 | func initKeyframeAnimation(){ |
关于图形的绘制
CAShapeLayer
是一个通过矢量图形
而不是bitmap
来绘制的图层子类。你指定诸如颜色和线宽等属性,用CGPath
来定义想要绘制的图形,最后CAShapeLayer
就自动渲染出来了。当然,你也可以用Core Graphics
直接向原始的CALyer
的内容中绘制一个路径,相比直下,使用CAShapeLayer
有以下一些优点:
- 渲染快速。
CAShapeLayer
使用了硬件加速,绘制同一图形会比用Core Graphics
快很多。 - 高效使用内存。
一个CAShapeLayer
不需要像普通CALayer一样创建一个寄宿图形(CALyer的contents属性,如果要给contents赋值就是layer.contents = (__bridge id)image.CGImage,所以占用内存大),所以无论有多大,都不会占用太多的内存。 - 不会被图层边界剪裁掉。
一个CAShapeLayer
可以在边界之外绘制。
你的图层路径不会像在使用Core Graphics的普通CALayer一样被剪裁掉。 - 不会出现像素化。
当你给CAShapeLayer
做3D变换时,它不像一个有寄宿图的普通图层一样变得像素化。
源代码地址
上面说的所有动画源代码地址