动画
在使用Core Animation开发动画的本质就是将CALayer中的内容转化为位图从而供硬件操作。
通过beginAnimations:context:和commitAnimations创建的动画是显式动画。
通过UIView的animateWithDuration:animations:方法创建的动画隐式是动画。
CALayer本身并不包含在UIKit中,它不能响应事件。由于CALayer在设计之初就考虑它的动画操作功能,CALayer很多属性在修改时都能形成动画效果,这种属性称为“隐式动画属性”。
但是对于UIView的根图层而言属性的修改并不形成动画效果,因为很多情况下根图层更多的充当容器的做用,如果它的属性变动形成动画效果会直接影响子图层。
layer的层次结构Layer Tree,这种层次结构分为以下三种:
- 
Model Tree :也就是我们通常所说的layer。 
- 
Presentation Tree:呈现出来的layer,也就是我们做动画时你看到的那个layer,可以通过layer.presentationLayer获得。 
- 
Render Tree :私有,无法访问。主要是对Present 
当设置removedOnCompletion 属性为NO以及fillMode属性为kCAFillModeForwards时,也并未改变model tree的位置,但是可以使动画结束后,防止presentation tree被移除并回到动画开始的位置。所以并不建议使用removedOnCompletion配合fillMode的方式来实现动画结束时,图层不跳转回原位的实现,我们应该在动画开始或者结束时重新设置它的位置。
//暂停动画
-(void)animationPause{
    //获取当前layer的动画媒体时间
    CFTimeInterval interval = [_aniLayer convertTime:CACurrentMediaTime() toLayer:nil];
    //设置时间偏移量,保证停留在当前位置
    _aniLayer.timeOffset = interval;
    //暂定动画
    _aniLayer.speed = 0;
}
//恢复动画
-(void)animationResume{
    //获取暂停的时间
    CFTimeInterval beginTime = CACurrentMediaTime() - _aniLayer.timeOffset;
    //设置偏移量
    _aniLayer.timeOffset = 0;
    //设置开始时间
    _aniLayer.beginTime = beginTime;
    //开始动画
    _aniLayer.speed = 1;
}
(2)如果没有委托或委托中没有实现-actionForLayer:forKey:方法,图层会检查actions字典,actions字典是属性名称对应行为的映射字典。 //
self.colorLayer.actions = @{@"backgroundColor":transiton};(3)如果actions字典中没有对应的属性名称,图层就检查style字典
(4)如果style中也没有对应的行为,那么图层将直接调用-defaultActionForKey:方法,
搜索完,-actionForKey:方法要么返回空(不会有动画发生),要么是CAAction协议对应的对象,然后CALayer拿这个结果对先前和当前的值做动画。
[CATransaction setDisableActions:YES];可通过此方法来禁用隐式动画----[UIView setAnimationsEnabled:NO];CATransaction的一部分,它可以同时对多个layer的属性进行修改,然后成批的将将多个图层树包装起来,一次性发送到渲染服务进程。CATransaction事务对象被分为implicit和explicit两种类型,分别对应隐式和显式。implicit transaction会被投递到线程的下一个runloop完成处理:API来显式的使用事务类,并且手动提交给渲染服务进程,这种做法被称作推进过渡。推进过渡会生成一个默认时长为0.25s时长的动画效果来完成属性值的修改。CAAction行为来帮助自己完成属性修改的行为。代理方法actionForLayer:forKey:允许三种返回的数据格式来完成不同的修改动作:- 
空对象 UIView在响应代理时默认会返回一个NSNull对象,表示属性修改后,不实现任何的动作,根据修改后的属性值直接更新视图。但UIView不总是会返回空对象,如果layer的修改发生在[UIView animatedXXX]接口的block中,每一个修改的属性值UIView都会返回对应的CABasicAnimation对象来进行动画修改//这是是显示动画
- nil对象     手动创建并添加到视图上的CALayer或其子类在属性修改时,没有获取到具体的修改行为。此时被修改的属性会被CATransaction记录,最终在下一个runloop的回调中生成动画来响应本次属性修改。由于这个过程非开发者主动完成的,因此这种动画被称作隐式动画
- CAAction的子类 如果返回的是- CAAction对象,会直接开始动画来响应图层属性的修改。一般返回的对象多为- CABasicAnimation类型,对象中包装了- 动画时长、- 动画初始/结束状态、- 动画时间曲线等关键信息。当- CAAction对象被返回时,会立刻执行动作来响应本次属性修改
隐式动画的修改最终由CATransaction事务完成,它在主线程的runloop注册了一个监听者,具体回调发生在before waiting阶段。在回调中会将所有implicit transactions以动画的形式展示。
在transaction回调结束时已经将图层树提交给渲染服务进程了,因此之后即便主线程发生卡顿,也不会影响渲染服务进程的工作。而早于transaction回调发生的卡顿会导致应用不能将图层树及时的提交到渲染服务进程,从而造成了动画开始前的界面停滞现象。
实际在应用使用中,即便是手指不离开屏幕,cell依旧能够展示各种动画。因此可以推断出transaction至少还注册了UITracking这个模式下的runloop监听处理
 
                    
                 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号