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

UIView.animate动画锁屏或切后台后停止,有什么替代实现方案?

iOS UIView 动画切后台/锁屏解锁后停止的解决方法

问题根因

这是iOS系统的默认行为:应用进入后台或锁屏时,系统会自动移除所有视图Layer上附着的动画,回到前台后不会自动恢复,因此动画会直接停止。

解决方案

因为你的三个关联动画需要和计数器同步,核心思路是监听应用回到前台的通知,每次进入前台时按照当前计数器的进度重新启动动画,保证三者同步。

步骤1:封装可对齐进度的动画启动方法

把三个动画的逻辑统一封装到独立方法中,通过当前计数器的剩余时间计算动画启动偏移量,避免重启动画后和计数器不同步:

// 这里假设你持有当前倒计时剩余时间的变量:remainingCountdown,单位为秒
@objc func restartFocusAnimations() {
    // 先清理所有残留的旧动画,避免冲突
    mainFocusLabel.layer.removeAllAnimations()
    // 另外两个关联动画对应的视图/图层也在这里清理旧动画,示例:
    // glowEffectLayer.removeAllAnimations()
    // fadeAnimateView.layer.removeAllAnimations()
    
    // 动画总周期是20秒:10秒放大 + 10秒缩小
    let totalCycle: TimeInterval = 20
    // 计算当前已走的时长,对总周期取余得到当前动画位置
    let elapsedTime = totalCycle - remainingCountdown.truncatingRemainder(dividingBy: totalCycle)
    // 计算负延迟,让动画直接从当前进度开始播放,而不是从头开始
    let startOffset = -elapsedTime

    // 重启缩放动画
    UIView.animateKeyframes(withDuration: 10, delay: startOffset, options: [.autoreverse, .repeat, .beginFromCurrentState]) {
        UIView.addKeyframe(withRelativeStartTime: 0.0, relativeDuration: 1.0) {
            // 如果要作用于MainFocusStack,替换为对应的StackView实例即可
            self.mainFocusLabel.transform = CGAffineTransform(scaleX: 1.3, y: 1.3)
        }
    }
    
    // 同步启动另外两个关联动画,使用相同的startOffset保证三者和计数器完全对齐
    // 这里补充你的发光效果、透明度变化动画代码即可
}

步骤2:监听前台通知,自动重启动画

在视图生命周期中添加通知监听,应用每次回到前台时自动调用上面的动画重启方法:

override func viewDidLoad() {
    super.viewDidLoad()
    // 监听应用即将进入前台的通知
    NotificationCenter.default.addObserver(
        self,
        selector: #selector(restartFocusAnimations),
        name: UIApplication.willEnterForegroundNotification,
        object: nil
    )
    // 页面加载完成后首次启动动画
    restartFocusAnimations()
}

// 页面销毁时移除通知,避免内存泄漏
deinit {
    NotificationCenter.default.removeObserver(
        self,
        name: UIApplication.willEnterForegroundNotification,
        object: nil
    )
}

注意事项

  • 动画参数添加.beginFromCurrentState,可避免动画重启时出现视觉跳变
  • 如果你的计数器进入后台会暂停,可在收到UIApplication.didEnterBackgroundNotification通知时记录当前的动画进度,回到前台时用记录的进度计算startOffset即可
  • 三个关联动画必须在同一个方法内同步启动,使用相同的startOffset参数,保证三者完全同步

内容的提问来源于stack exchange,提问作者Rem Biths Wind

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 03:15:01