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

UIViewPropertyAnimator调用stopAnimation后仍运行,触发finishAnimation崩溃

解决UIViewPropertyAnimator切换时的崩溃问题

这问题我之前也碰到过!核心原因是你对stopAnimation(_:)的参数行为理解有点偏差,导致调用时机不对触发了崩溃。

为什么调用stopAnimation(false)后动画器仍处于运行状态?

你调用oldValue.stopAnimation(false)时,这个方法并不是立即停止动画的——它的作用是让动画继续运行到当前的目标状态(比如交互式拖拽时的当前终点),然后才会异步切换到停止状态。所以在你调用完这个方法的瞬间,动画器其实还在运行中,这时候你立刻调用finishAnimation(at:)就会触发那个finishAnimationAtPosition: should only be called on a stopped animator!的崩溃,因为这个方法要求动画器必须处于「已停止」或「已暂停」的状态。

稳妥的解决方案

针对卡片滑动切换的场景,你需要在替换旧动画器时,确保它能被安全地终止并完成,推荐两种处理方式:

方式一:立即暂停并完成动画(适合快速切换场景)

这种方式会立刻暂停旧动画,然后直接跳转到动画结束状态,确保旧动画器不会在释放时引发崩溃:

fileprivate var runningAnimator: UIViewPropertyAnimator? {
    didSet {
        guard let oldAnimator = oldValue, oldAnimator.state != .finished else { return }
        
        // 如果动画正在运行,先立即暂停
        if oldAnimator.isRunning {
            oldAnimator.pauseAnimation()
        }
        
        // 现在动画处于暂停状态,可以安全调用finishAnimation
        oldAnimator.finishAnimation(at: .end)
    }
}

方式二:立即停止并完成动画(更直接的终止方式)

如果你不需要等待旧动画完成当前过渡,也可以用stopAnimation(true)立即终止动画,然后完成:

fileprivate var runningAnimator: UIViewPropertyAnimator? {
    didSet {
        guard let oldAnimator = oldValue, oldAnimator.state != .finished else { return }
        
        // 立即停止动画,进入stopped状态
        oldAnimator.stopAnimation(true)
        // 安全完成动画
        oldAnimator.finishAnimation(at: .end)
    }
}

额外的双重保险:ViewController销毁时的清理

为了彻底避免释放时的崩溃,建议在VC的deinit方法里也加上清理逻辑:

deinit {
    guard let animator = runningAnimator, animator.state != .finished else { return }
    
    if animator.isRunning {
        animator.pauseAnimation()
    }
    animator.finishAnimation(at: .end)
}

关键要点总结

  • stopAnimation(false)是异步完成停止的,不能在调用后立刻执行finishAnimation;
  • 必须确保动画器处于「暂停」或「已停止」状态时,才能调用finishAnimation(at:);
  • 无论何时替换动画器,都要先处理旧动画器的状态,避免它在后台残留导致崩溃。

内容的提问来源于stack exchange,提问作者Milan Nosáľ

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 08:41:42