阅读器翻页动画优化总结

2,515 阅读2分钟

最近在优化阅读器的翻页方式,我们阅读器支持仿真翻页、覆盖翻页和无动画翻页三种翻页模式,仿真翻页和无动画翻页是使用系统的 UIPageViewController 实现的,覆盖翻页是使用邓泽淼开源的DZMCoverAnimation实现的。

DZMCoverAnimation 中,使用 [UIView animationWithDuration:animations:completion:] 实现覆盖翻页的过渡动画。根据苹果的官方文档 animationWithDuration:animations:completion: 方法在执行动画的过程中,会使所有的用户手势都会暂时性失效。

近期我们有个需求,需要实现覆盖翻页模式下的快速翻页效果即用户快速点击都能触发覆盖翻页效果。使用   animationWithDuration:animations:completion:  方法显然已经不能满足这个需求,这时候就需要使用 CAAnimation 来实现动画效果。

因为 Core Animation 动画的执行过程都是在后台,所以不会阻塞主线程。

所以这里我们利用 CABasicAnimation 来替代 animationWithDuration:animations:completion: 实现过渡动画。

CABasicAnimation的用法

使用 animationWithKeyPath: 对CABasicAnimation进行实例化,通过传入指定的keyPath字符串,指名具体的动画的方式,下面是动画过程一些相关属性的说明。

属性 说明
duration 动画的时长
repeatCount 重复的次数。不停重复设置为 HUGE_VALF
repeatDuration 设置动画的时间。在该时间内动画一直执行,不计次数。
beginTime 指定动画开始的时间。从开始延迟几秒的话,设置为【CACurrentMediaTime() + 秒数】 的方式
timingFunction 设置动画的速度变化
autoreverses 动画结束时是否执行逆动画
fromValue 所改变属性的起始值
toValue 所改变属性的结束时的值
byValue 所改变属性相同起始值的改变量

参考示例:

CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"position.x"];
animation.fromValue = @0;
animation.toValue = @100;
animation.duration = 0.3;
[self.view.layer addAnimation:animation forKey:@"layer.position"];

防止动画结束后回到初始状态

CABasicAnimation 执行完动画后,默认会恢复到初始状态,这是因为我们给一个视图添加动画时,真正移动的并不是视图本身,而是presentation layer的一个缓存,动画开始时,presentation layer开始移动,原始layer隐藏,动画结束时,presentation layer从屏幕上移除,原始layer显示。这也就是视图在动画结束后又恢复到原始状态的原因。

要想防止动画结束后回到初始状态,可以设置 fillMode = kCAFillModeForwards 和 removedOnCompletion = NO 。这是因为 kCAFillModeForwards 表示动画结束后layer的状态保持在动画的最后一帧, removedOnCompletion = NO 表示动画结束后presentation layer不做移除。

最终,结合上述两点,就可以利用 CABasicAnimation 代替animationWithDuration:animations:completion: 实现覆盖翻页动画过渡效果。