You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何获取视图层进度条动画暂停时的完成百分比?

解决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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 06:57:42