事务:
事务实际上是Core Animation用来包含一系列属性动画集合的机制,任何用指定事务去改变可以做动画的图层属性都不会立刻发生变化,而是当事务一旦提交的时候开始用一个动画过渡到新值。
事务是通过CATransaction类来管理的
CATransaction无法创建,但是可以通过begin和commit来进行压栈和出栈,通过setAnimationDuration:设置时间
完成块:
事务中提供了一个方法setCompletionBlock:方法来执行动画完成后的要执行的代码
图层行为:
如果直接对UIView的Layer使用动画你会发现动画效果是没有的,因为CALayer的动画被关闭了。
让我们先来看一下CALayer动画的执行过程,首先当CALayer的一个属性被修改时
1.会调用actionForKey:方法来传递属性名称
2.查看图层是否实现了CALayerDelegate中的actionForLayer:forKey方法有则返回结果,没有则3
3.没有实现actionForLayer:forKey方法图层会去检查包含名称对应行为映射的actions字典
如果有返回,如果没有4
4.没有action字典则去他的style字典中搜索属性名,如果有返回,如果没有5
5.如果没有则执行一个标准/默认的 defaultActionForKey方法
于是返回结果要么是nil 要么是CAAction协议对应的对象 于是UIView可以通过返回nil来关闭动画,或者通过CATransAction的setDisableActions:方法来关闭动画
总结UIView下使用动画:
A. UIView关联的图层禁用了隐式动画,对这种图层做动画的唯一办法就是使用UIView的动画函数(而不是依赖CATransaction),或者继承UIView,并覆盖-actionForLayer:forKey:方法,或者直接创建一个显式动画(具体细节见第八章)。
B. 对于单独存在的图层,我们可以通过实现图层的-actionForLayer:forKey:委托方法,或者提供一个actions字典来控制隐式动画。
行为:
总结一下,我们知道了如下几点
UIView关联的图层禁用了隐式动画,对这种图层做动画的唯一办法就是使用UIView的动画函数(而不是依赖CATransaction),或者继承UIView,并覆盖-actionForLayer:forKey:方法,或者直接创建一个显式动画(具体细节见第八章)。(意思就是,你不能对一个UIView下的Layer使用隐式动画)
对于单独存在的图层,我们可以通过实现图层的-actionForLayer:forKey:委托方法,或者提供一个actions字典来控制隐式动画。
行为通常是一个被Core Animation隐式调用的显式动画对象
呈现和模型:
由于CALayer的显示顺序问题 ,我们会发现CALayer在赋值之后并不是直接变化的,而是通过一段时间的渐变更新。
于是在给属性赋值的时候,是定义了图层的显示模型,他决定了在CALayer的变化过程中的变化轨迹。
而从初始图层变化到最终图层之间是通过呈现图层来显示的,呈现图层里面记录了当前状态下的图层的属性值,可以通过presentationLayer方法来访问。
大多数情况下,你不需要直接访问呈现图层,你可以通过和模型图层的交互,来让Core Animation更新显示。两种情况下呈现图层会变得很有用,一个是同步动画,一个是处理用户交互。(当你在执行一个隐式/属性动画的时候,在这个动画过程中,你想要施加动作于图层,你就需要作用于呈现图层!)
如果你在实现一个基于定时器的动画,而不仅仅是基于事务的动画,这个时候准确地知道在某一时刻图层显示在什么位置就会对正确摆放图层很有用了。
如果你想让你做动画的图层响应用户输入(在动画变化过程中,如果对CALayer添加是没有效果的,所以需要对呈现层添加),你可以使用-hitTest:方法来判断指定图层是否被触摸,这时候对呈现图层而不是模型图层调用-hitTest:会显得更有意义,因为呈现图层代表了用户当前看到的图层位置,而不是当前动画结束之后的位置。
网友评论