Layer动画的停止与恢复
来源:互联网 发布:国际组织工作 知乎 编辑:程序博客网 时间:2024/06/05 19:37
CALayer
和CAAnimation
都实现了CAMediaTiming
协议,可以通过CALayer
中实现的协议中的属性来控制动画。
停止动画:通过将speed设置为0,并将timeOffset调整到合适的值。
Apple 文档说明
/* The rate of the layer. Used to scale parent time to local time, e.g. if rate is 2, local time progresses twice as fast as parent time. Defaults to 1. */@property float speed;/* Additional offset in active local time. i.e. to convert from parent time tp to active local time t: t = (tp - begin) * speed + offset.One use of this is to "pause" a layer by setting `speed' to zero and `offset' to a suitable value. Defaults to 0. */@property CFTimeInterval timeOffset;
而恢复动画,除了上面两个属性,还需要配合beginTime
属性来让动画在正确的时间、位置恢复
##方法一// 停止- (void)pauseLayer:(CALayer*)layer{ CFTimeInterval pausedTime = [layer convertTime:CACurrentMediaTime() fromLayer:nil]; // 让CALayer的时间停止走动 layer.speed = 0.0; // 让CALayer的时间停留在pausedTime这个时刻 layer.timeOffset = pausedTime;}
恢复动画:
- (void)resumeLayer:(CALayer*)layer{ CFTimeInterval pausedTime = layer.timeOffset; // 1. 让CALayer的时间继续行走 layer.speed = 1.0; // 2. 取消上次记录的停留时刻 layer.timeOffset = 0.0; // 3. 取消上次设置的时间 layer.beginTime = 0.0; // 可以放在pauseLayer:方法中方便理解 // 4. 计算暂停的时间(这里也可以用CACurrentMediaTime()-pausedTime) CFTimeInterval timeSincePause = [layer convertTime:CACurrentMediaTime() fromLayer:nil] - pausedTime; // 5. 设置相对于父坐标系的开始时间(往后退timeSincePause) layer.beginTime = timeSincePause;}
以上方法中有几点较为难以理解的地方,待后续解读。
1 . CALayer
中beginTime的含义。CAAnimation
的beginTime表现为从duration
的哪个点开始动画。如果不做停止/恢复动画的动作,给CALayer
设置一个动画,并设置它的beginTime
属性,结果对动画的表现并没有任何影响。
疑点1解答:beginTime须设置为与层时间相关的值,如CACurrentMediaTime() + 1, 将会延迟1s开始动画;而不能直接设置为 1s。另外beginTime可以在CAGroupAnimation中控制某个动画在组动画中的起始时间。
2 . 恢复动画时,先设置layer.beginTime = 0
随后马上又设置layer.beginTime = timeSincePause
。如果少了第一句(layer.beginTime = 0
),在动画第二次恢复时,不会衔接暂停时的位置,而是取决于你暂停了多少时间,这段时间内layer
本应该动画到哪个位置,它就会从那个位置恢复动画。但对第一次恢复没有影响。
第2点解答:恢复动画时,先设`layer.beginTime = 0.0` 是为了后一句代码`[layer convertTime:CACurrentMediaTime() fromLayer:nil]` 能得到正确的层上的时间,如果没有layer.beginTime = 0.0, 则convert出的时间将会是上次停止动画的时间pausedTime;layer.beginTime = 0.0 这句代码可以放在停止动画方法中去。
3 . 其中,beginTime
、timeOffset
于CACurrentMediaTime()
之间的关系。
方法二
// 停止动画- (void)pauseAnimation{ CFTimeInterval current = CACurrentMediaTime(); CFTimeInterval pauseTime = current - layer.beginTime; /* 实际此处 [layer convertTime:CACurrentMediaTime() fromLayer:nil] == current - layer.beginTime == pauseTime */ layer.speed = 0; layer.timeOffset = pauseTime; layer.beginTime = 0.; }- (void)resumeAnimation{ CFTimeInterval pauseTime = layer.timeOffset; CFTimeInterval timeSincePause = CACurrentMediaTime() - pauseTime; /* [layer convertTime:CACurrentMediaTime() fromLayer:nil] == pauseTime */ layer.speed = 1.0; layer.timeOffset = 0.0; layer.beginTime = timeSincePause;}
timeSincePause 是动画停止了多长时间,动画停止了而层上的时间CACurrentMediaTime()
仍然在往前走,因此需要将layer.beginTime
往回退,才能让动画在正确的时间位置恢复。
参考:
1. CoreAnimation – Ljson
2. 控制动画的时间
- Layer动画的停止与恢复
- Layer动画的停止和恢复
- CSS动画的停止与监听
- 郁闷的Layer动画
- 如何在Property Animator动画过程中,使动画的View停止动画且恢复到原来状态
- iOS动画的暂停与恢复
- 自定义 Layer 属性的动画
- 自定义 Layer 属性的动画
- 自定义 Layer 属性的动画
- 自定义 Layer 属性的动画
- iOS Layer动画的KeyPath
- 浏览器的停止功能(esc键)与gif动画停止变换的关系
- Layer动画
- 关键帧动画的停止
- 实现动画的停止功能
- Android MediaPlayer 播放停止与恢复
- WPF控制动画开始、停止、暂停和恢复
- WPF控制动画开始、停止、暂停和恢复
- 乘法3
- eclipse android adt安装后没有菜单栏没有相应的插件?
- 图片全屏显示——js插件
- 三位数乘以一位数
- 论如何写出一篇高质量的英文论文
- Layer动画的停止与恢复
- vb18
- 解决Allocate exception for servlet jsp的问题
- 每个Xcode开发者应该知道的七个使用技巧
- 时间处理工具类
- 333
- 3乘1
- n乘一位数
- 2位数乘以一位数