如何获取视图层进度条动画暂停时的完成百分比?
解决UIView动画暂停时获取完成百分比的问题
我来帮你搞定这个问题!你现在用UIView的animate方法实现进度条宽度动画,能完成暂停和恢复,但拿不到暂停时的完成百分比——其实核心是要从Core Animation的Layer时间属性入手,因为UIView的动画本质是封装了CALayer的隐式动画,直接操作UIView的frame时,动画实际作用在它的layer上。
下面是具体的实现方案:
1. 先定义必要的属性
首先我们需要保存动画的总时长,以及记录暂停时的时间点,方便后续计算进度:
// 动画总时长,和你animate方法里的3秒对应 let totalAnimationDuration: TimeInterval = 3 // 记录暂停时的Layer时间 var pausedLayerTime: CFTimeInterval = 0
2. 完善暂停动画函数,同时计算进度
修改你的pauseLayer函数,在暂停的同时计算当前动画的完成百分比:
func pauseLayer(layer: CALayer) { // 将当前系统媒体时间转换为Layer自身时间轴的时间 pausedLayerTime = layer.convertTime(CACurrentMediaTime(), from: nil) // 暂停Layer动画 layer.speed = 0.0 layer.timeOffset = pausedLayerTime // 计算已运行时间:暂停时间减去动画开始时间 let elapsedTime = pausedLayerTime - layer.beginTime // 计算完成百分比,乘以100转为百分比格式 let completionProgress = elapsedTime / totalAnimationDuration print("当前进度条完成百分比:\(completionProgress * 100)%") // 这里可以把completionProgress保存下来,用于更新UI或者其他逻辑 }
3. 恢复动画的函数
对应的恢复动画函数也要调整,确保动画能从暂停点继续:
func resumeLayer(layer: CALayer) { let pausedTime = layer.timeOffset // 恢复Layer的动画速度 layer.speed = 1.0 layer.timeOffset = 0.0 layer.beginTime = 0.0 // 计算暂停到现在的时间差,更新Layer的开始时间 let timeSincePause = layer.convertTime(CACurrentMediaTime(), from: nil) - pausedTime layer.beginTime = timeSincePause }
关键逻辑说明
- Core Animation的Layer通过
beginTime(动画开始时间)、timeOffset(时间偏移)、speed(动画速度)这三个属性控制时间轴。 - 暂停时我们把
speed设为0,记录当前系统时间转换到Layer时间轴的数值,用这个数值减去beginTime就能得到动画已经运行的时长。 - 用已运行时长除以动画总时长,就能得到精确的完成百分比。
调用的时候,直接传入进度条的Layer即可:
// 暂停时 pauseLayer(layer: progressView.layer) // 恢复时 resumeLayer(layer: progressView.layer)
内容的提问来源于stack exchange,提问作者skkrish
相关产品推荐
相关产品推荐

