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

Swift中进度条动画无法正确重复问题求助

Swift进度条重复动画异常问题修复

问题核心

你的进度条重复动画异常,是因为前一次动画未完成就启动新动画,导致约束的动画状态叠加混乱,后续动画的起始状态被干扰,最终出现进度条跳转到视图外部的情况。

修复方案

  1. 启动新动画前,强制终止所有未完成的动画,清空混乱状态
  2. 调整约束重置与布局的顺序,确保每次动画的起始状态准确
  3. 可选添加动画完成回调,统一处理结束后的状态

修正后的代码

@objc private func updateCountdownLabel(_ notification: NSNotification) {
    // 终止所有正在进行的动画,避免状态冲突
    self.progressView.layer.removeAllAnimations()
    
    // 重置进度条到初始状态,更新约束后立即布局
    self.progressWidthAnchor.constant = 0
    self.layoutIfNeeded()
    
    if let timeRemaining = notification.userInfo?["timeRemaining"] as? Int {
        self.secondsRemaining = timeRemaining
        // 用倒计时剩余时长作为动画时长,贴合业务逻辑(原代码写死10应为笔误)
        self.animateProgress(width: 100, duration: timeRemaining)
    }
}

private func animateProgress(width: CGFloat, duration: Int) {
    UIView.animate(withDuration: TimeInterval(duration),
                   delay: TimeInterval(LocalConstants.animationDelayDuration),
                   options: .curveLinear) {
        self.progressWidthAnchor.constant = width
        self.layoutIfNeeded()
    } completion: { finished in
        // 动画完成后自动重置,避免下次启动时状态异常(可选)
        if finished {
            self.progressWidthAnchor.constant = 0
            self.layoutIfNeeded()
        }
    }
}

关键说明

  • 原代码中,通知多次触发时,前一次动画还在运行就直接修改约束常量,此时动画的中间状态会和新设置的初始值冲突,导致布局计算出错。removeAllAnimations()能让视图立即回到当前约束的实际状态,消除冲突。
  • 原animateProgress方法开头的layoutIfNeeded()是多余的,动画块内的layoutIfNeeded()才是触发平滑过渡的关键,外部提前布局反而可能打乱初始状态。

内容的提问来源于stack exchange,提问作者PR16

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 06:41:15