iOS 砖家纪实录iOSiOS

iOS核心动画高级技巧:第二部分-动画

2016-06-26  本文已影响1077人  SvenLearn

传送门:《iOS核心动画高级技巧》部分源码

CA利用RunLoop收集图层 Animatable属性 的修改(如backgroundColor等),并基于事务对【隐式动画】进行管理;简单来说隐式动画只能完成部分基础属性动画,而【显式动画】则通过 关键帧动画动画组 对属性动画提供更具体的控制或组合,通过 过渡 支持 NonAnimatable属性和图层树的变化;而【图层时间】介绍了Core Animation用来操作时间控制动画的机制:CAMediaTiming协议和层级关系时间,并给出了手动动画的通用解决方案;【缓冲】通过控制 速度 使动画更平滑更自然;如果需要实时控制动画/更强的交互控制动画,可以使用【基于定时器的动画】。
 
从结构上来说,CAAnimation包括计时函数(CAMediaTimingFunction)、一个图层委托(CALayerDelegate,用于反馈动画状态)和一个removedOnCompletion(标识动画是否该在结束后自动释放,默认YES ,为了防止内存泄露),另外还实现了以下协议:
  - CAAction (允许 CAAnimation 的子类提供图层行为)
  - CAMediaTiming (第九章“图层时间”将会详细解释)。

我发现一个很奇怪的问题:使用animation.beginTime有时导致动画失效、有时类似无序的timeOffset,未能实现延迟开始动画的功能???


一些常用的缓冲函数:
RBBAnimation
AHEasing

第七章:隐式动画

隐式动画:Core Animation在每个 RunLoop 周期中自动开始一次新的事务(RunLoop是iOS负责收集用户输入、处理定时器或者网络事件并且重新绘制屏幕的东西),即使不显式调用[CATransaction begin];开始一次事务,任何在一次RunLoop循环中Animatable属性的改变也会被集中起来,然后Core Animation根据图层行为和事务设置(默认0.25秒)去不断更新视图的这些属性在屏幕上的状态。

第八章:显式动画

8.1 CAAnimation体系结构

-(void)applyBasicAnimation:(CABasicAnimation *)animation toLayer:(CALayer *)layer{
  animation.fromValue = [layer.presentationLayer ?: layer valueForKeyPath:animation.keyPath];
 
  // note: this approach will only work if toValue != nil
  [CATransaction begin];
  [CATransaction setDisableActions:YES];
  [layer setValue:animation.toValue forKeyPath:animation.keyPath];
  [CATransaction commit];
 
  [layer addAnimation:animation forKey:nil];
}
        - 在动画之后更新(需结合KVC和fillMode) - CAAnimationDelegate
-(void)animationDidStop:(CABasicAnimation *)anim finished:(BOOL)flag
{
  // CAAnimation实现了KVC(键-值-编码)协议,于是你可以用-setValue:forKey:和-valueForKey:方法来存取属性。
  // 可以利用它来判断到底是哪个图层的调用
  // 另外,为了确保更新属性更新发生在动画返回初始状态之前,还得考虑fillMode!!!
  [CATransaction begin];
  [CATransaction setDisableActions:YES];
  self.colorLayer.backgroundColor = (__bridge CGColorRef)anim.toValue;
  [CATransaction commit];
}
kCATransitionFade //平滑的淡入淡出效果
 
kCATransitionPush  //从顶部滑动进入,但不像推送动画那样把老图层推走
kCATransitionMoveIn //新图层从边缘的一侧滑动进来,把旧图层从另一侧推出去的效果
kCATransitionReveal  //把原始的图层滑动出去来显示新的外观,而不是把新的图层滑动进入
+ [subtype](https://developer.apple.com/library/ios/documentation/GraphicsImaging/Reference/CATransition_class/index.html#//apple_ref/occ/instp/CATransition/subtype) - kCATransitionFromRight/Top/Left/Bottom
+ 对指定的图层一次只能使用一次CATransition
[self.imageView.layer addAnimation:transition forKey:nil];  //使用默认键 - kCATransition
+transitionFromView:toView:duration:options:completion://可能有图层树变化
+transitionWithView:duration:options:animations://图层树不变
UIGraphicsBeginImageContextWithOptions(self.view.bounds.size, YES, 0.0);
[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *coverImage = UIGraphicsGetImageFromCurrentImageContext();

8.2 在动画过程中取消动画


第九章:图层时间

Core Animation是如何跟踪时间的

CFTimeInterval time = CACurrentMediaTime(); // 马赫时间:对动画的时间测量提供了一个相对值
-(CFTimeInterval)convertTime:(CFTimeInterval)t from/toLayer:(CALayer *)l;

第十章:缓冲

使动画移动更平滑更自然


第十一章:基于定时器的动画

允许我们精确地控制一帧一帧展示;iOS按照每秒60次刷新屏幕,CAAnimation最机智的地方在于每次刷新需要展示的时候去计算插值和缓冲。

while (self.lastStep < frameTime) {
  cpSpaceStep(self.space, SIMULATION_STEP);
  self.lastStep += SIMULATION_STEP;
}
- 避免死亡螺旋
 + cpSpaceStep()的计算造成帧率延迟的塔罗牌堆积效应
上一篇 下一篇

猜你喜欢

热点阅读