alun-chen

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

1. Model Layer Tree(模型层树)和Presentation Layer Tree(表示层树)

   CALayer是动画产生的地方。当我们动画添加到Layer时,是不直接修改layer的属性的。所以CoreAnimation有两个layer层次结构:model layer tree(模型层树)和presentation layer tree(表示层树)。Model Layer Tree的Layers是我们直接看到layers的状态,Presentation Layer Tree的Layers是动画正在表现的值的近似

   我们可以这样来调用:

1 //模型层树
2 CALayer.modelLayer(CALayer)
3 //表示层树
4 CALayer.presentationLayer(CALayer)

   例如,我们运行一个动画改变position.x的值,让Layer由左向右运动(如下图)。

   我们发现在运动结束后,Layer会还原回原来的值。这是因为在默认情况下,动画在运行结束后,不会修改其Presentation Layer,也就是说,结束时会彻底移除Presentation Layer。通俗的来说,运行结束时Presentation Layer会回到Model Layer的值。

   如果想动画运行结束后还保留其结束后的值,则有下面两种方法可以修改。

   1)通过结束后的值来设置Layer的位置(推荐这种,因为这种方法使得动画完全可选)

 1     //移动动画position
 2     func addLayerAnimationPosition(layer: CALayer) {
 3         let animation = CABasicAnimation(keyPath: "position")
 4         animation.fromValue = NSValue(CGPoint: layer.position)
 5         //移动到的位置
 6         animation.toValue = NSValue(CGPoint: CGPointMake(120, 200))
 7         animation.duration = 3
 8 
 9         layer.addAnimation(animation, forKey: "addLayerAnimationPosition")
10 
11         //设置Layer结束后的位置
12         layer.position = CGPointMake(120, 200)
13     }

   2)通过kCAFillModeForward和removedOnCompletion防止结束时被移除

 1     //移动动画position
 2     func addLayerAnimationPosition(layer: CALayer) {
 3         let animation = CABasicAnimation(keyPath: "position")
 4         animation.fromValue = NSValue(CGPoint: layer.position)
 5         //移动到的位置
 6         animation.toValue = NSValue(CGPoint: CGPointMake(120, 200))
 7         animation.duration = 3
 8         //运动后的位置保持不变
 9         animation.removedOnCompletion = false
10         animation.fillMode = kCAFillModeForwards
11     
12         layer.addAnimation(animation, forKey: "addLayerAnimationPosition")
13     }

 

   我们可以看到,从上面的方法可以得到动画结束后不变,但是请注意的一点是这样会造成额外的开销,因为渲染器回去进行额外的绘画工作。

 

2.动画的beginTime与被复制性

   动画当被添加到Layer时,Layer会复制这份动画。这使我们在多个view中重用同一个动画非常有用。比如我们创建一个Layer的动画由左向右运动,当运动完成时在过1秒钟,此Layer会变透明。

 1         //----------先由左向右运动,然后边透明-----------
 2         //添加由左向右的动画
 3         let ani = CABasicAnimation.init(keyPath: "position.x")
 4         ani.toValue = 200
 5         ani.duration = 3
 6         ani.removedOnCompletion = false
 7         ani.fillMode = kCAFillModeForwards
 8         calayer.addAnimation(ani, forKey: "position_x")
 9         
10         //上面的动画执行时,已经被layer copy一份了,所以要想改变animation的值不会影响其动画效果
11         //重用上面的动画,当运动完成后+3秒,执行下一动画——变透明
12         ani.keyPath = "opacity"
13         ani.beginTime = CACurrentMediaTime() + 3
14         ani.toValue = 0
15         calayer.addAnimation(ani, forKey: "opacity")

 

 

 如果想了解动画与bezier曲线与layer的结合,可以看CAShapeLayer、UIBezierPath与Animation的结合

 

 

 

 

 

 

 

 

 

 

   

posted on 2016-04-10 22:13  alun-chen  阅读(951)  评论(0编辑  收藏  举报