前言
在上一篇《认识CoreAnimation》中笔者介绍了系统的动画库CoreAnimation
,使用动画库有很多好处,这里就不再进行重复叙述。那么本篇将承接上一篇的内容,使用提到的基础的动画相关类来实现动画效果,效果图放上:
![](http://file.zhishichong.com/images/article/20161028/7cc829d3gw1f7r20946cxg207t089dlb.gif)
大体上可以看到demo主要是渐变以及形变两种动画,在更早之前的文章,我们就使用UIView
的动画接口完成过相同的动画,而这次将换成CoreAnimation
来完成这些工作
关于图层
在iOS中,每一个UIView
都拥有一个与之绑定的CALayer
图层对象,其负责视图内容的绘制与显示。跟前者一样,CALayer
也拥有树状的子图层结构,以及相似的接口方法。CALayer
是图层的基类,主要提供了视图显示范围、图层结构接口等属性,我们通过使用它的子类。下面是一段在控制器的界面中心添加一个圆形的紫色图层:
1 2 3 4 5 6 7 8 |
override func viewDidLoad() { super.viewDidLoad() let layer = CAShapeLayer() layer.fillColor = UIColor.purpleColor().CGColor layer.path = UIBezierPath(arcCenter: CGPoint(x: UIScreen.mainScreen().bounds.width / 2, y: UIScreen.mainScreen().bounds.height / 2), radius: 100, startAngle: 0, endAngle: 2.0*CGFloat(M_PI), clockwise: false).CGPath self.view.layer.addSublayer(layer) } |
同样的,每一个CALayer
存在一个sublayers
的数组属性,我们也可以遍历这个数组来完成移除子视图之类的操作:
1 2 3 4 |
for sublayer in self.view.layer.sublayers! { print("\(sublayer)") sublayer.removeFromSuperlayer() } |
由于核心动画框架的动画都是基于CALayer
的图层进行添加实现的,所以图层的添加移除方法是最常用的方法。当然,还有一个addAnimation(anim:forKey:)
接口用来给图层添加动画
基础动画
基础动画CABasicAnimation
是最常用来实现动画效果的动画类,其继承自CAAnimation
动画基类,为图层动画效果实现了一个keyPath
属性,我们通过设置这个属性来为对应的keyPath
属性值执行动画效果。动画类提供了fromValue
和toValue
两个属性用来设置动画的起始和结束的值,比如下面一段代码让添加到视图上的紫色图层变得透明:
1 2 3 4 5 6 7 |
@IBAction func actionToAnimatedLayer(sender: AnyObject) { let animation = CABasicAnimation(keyPath: "opacity") animation.fromValue = NSNumber(double: 1) animation.toValue = NSNumber(double: 0) animation.duration = 1 layer.addAnimation(animation, forKey: nil) } |
上面的代码用动画表现了在1秒内让图层的opacity
属性从1
到0
的过程。但上面不难看出在动画结束之后,紫色的图层没有保持opacity
等于0
的状态,而是回到了动画最开始的状态。这是为什么呢?
在上一篇中笔者提到过在每一个CALayer
中存在着模型
、呈现
、渲染
三种图层树,正是这些图层树共同作用来完成隐式动画。那么使用核心动画的时候,实际上CABasicAnimation
会根据动画时长计算出每一帧的动画属性的值,然后实时提交给呈现树
来展示对应时间点的视图效果,在动画结束时CAAnimation
对象会自动从图层上移除。而由于在整个动画过程模型树
的值没有改变,所以在动画结束的时候呈现树
会再次从模型树
获取图层的属性重新绘制。对此,存在这几种解决方案:
- 在实现动画的时候同时修改
opacity
,保证模型树的数据同步
12345678910@IBAction func actionToAnimatedLayer(sender: AnyObject) {let animation = CABasicAnimation(keyPath: "opacity")animation.fromValue = NSNumber(double: 1)animation.toValue = NSNumber(double: 0)animation.fillMode = kCAFillModeForwardsanimation.removedOnCompletion = falseanimation.duration = 1layer.addAnimation(animation, forKey: nil)} - 取消
CAAnimation
的自动移除,并且设置在动画结束后保持动画的结束状态
123456789@IBAction func actionToAnimatedLayer(sender: AnyObject) {let animation = CABasicAnimation(keyPath: "opacity")animation.fromValue = NSNumber-h"> "opacity")animation.fromValue = NSNumber画库有很多好处,这里就不再进行重复叙述。那么本篇将承接上一篇的内容,使用提到的基础的动画相关类来实现动画效果,效果图放上:大体上可以看到demo主要是渐变以及形变两种动画,在更早之前的文章,我们就使用
UIView
的动画接口完成过相同的动画,而这次将换成CoreAnimation
来完成这些工作关于图层
在iOS中,每一个
UIView
都拥有一个与之绑定的CALayer
图层对象,其负责视图内容的绘制与显示。跟前者一样,CALayer
也拥有树状的子图层结构,以及相似的接口方法。CALayer
是图层的基类,主要提供了视图显示范围、图层结构接口等属性,我们通过使用它的子类。下面是一段在控制器的界面中心添加一个圆形的紫色图层:12345678override func viewDidLoad() {super.viewDidLoad()let layer = CAShapeLayer()layer.fillColor = UIColor.purpleColor().CGColorlayer.path = UIBezierPath(arcCenter: CGPoint(x: UIScreen.mainScreen().bounds.width / 2, y: UIScreen.mainScreen().bounds.height / 2), radius: 100, startAngle: 0, endAngle: 2.0*CGFloat(M_PI), clockwise: false).CGPathself.view.layer.addSublayer(layer)}同样的,每一个
CALayer
存在一个sublayers
的数组属性,我们也可以遍历这个数组来完成移除子视图之类的操作:1234for sublayer in self.view.layer.sublayers! {print("\(sublayer)")sublayer.removeFromSuperlayer()}由于核心动画框架的动画都是基于
CALayer
的图层进行添加实现的,所以图层的添加移除方法是最常用的方法。当然,还有一个addAnimation(anim:forKey:)
接口用来给图层添加动画基础动画
基础动画
CABasicAnimation
是最常用来实现动画效果的动画类,其继承自CAAnimation
动画基类,为图层动画效果实现了一个keyPath
属性,我们通过设置这个属性来为对应的keyPath
属性值执行动画效果。动画类提供了fromValue
和toValue
两个属性用来设置动画的起始和结束的值,比如下面一段代码让添加到视图上的紫色图层变得透明:1234567@IBAction func actionToAnimatedLayer(sender: AnyObject) {let animation = CABasicAnimation(keyPath: "opacity")animation.fromValue = NSNumber(double: 1)animation.toValue = NSNumber(double: 0)animation.duration = 1layer.addAnimation(animation, forKey: nil)}上面的代码用动画表现了在1秒内让图层的
opacity
属性从1
到0
的过程。但上面不难看出在动画结束之后,紫色的图层没有保持opacity
等于0
的状态,而是回到了动画最开始的状态。这是为什么呢?在上一篇中笔者提到过在每一个
CALayer
中存在着模型
、呈现
、渲染
三种图层树,正是这些图层树共同作用来完成隐式动画。那么使用核心动画的时候,实际上CABasicAnimation
会根据动画时长计算出每一帧的动画属性的值,然后实时提交给呈现树
来展示对应时间点的视图效果,在动画结束时CAAnimation
对象会自动从图层上移除。而由于在整个动画过程模型树
的值没有改变,所以在动画结束的时候呈现树
会再次从模型树
获取图层的属性重新绘制。对此,存在这几种解决方案:- 在实现动画的时候同时修改
opacity
,保证模型树的数据同步
12345678910@IBAction func actionToAnimatedLayer(sender: AnyObject) {let animation = CABasicAnimation(keyPath: "opacity")animation.fromValue = NSNumber(double: 1)animation.toValue = NSNumber(double: 0)animation.fillMode = kCAFillModeForwardsanimation.removedOnCompletion = falseanimation.duration = 1layer.addAnimation(animation, forKey: nil)} - 取消
CAAnimation
的自动移除,并且设置在动画结束后保持动画的结束状态
123456789@IBAction func actionToAnimatedLayer(sender:
- 在实现动画的时候同时修改