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

为什么UIViewPropertyAnimator在completion块中所有state判断都返回false

问题原因分析

1. 所有state判断都为false的原因

该问题的核心原因是可选类型判断错误:
如果你的self.animator声明为可选类型(UIViewPropertyAnimator?),直接通过可选链调用self.animator.state得到的返回值是UIViewPropertyAnimator.State?(可选枚举类型),直接和非可选的枚举值比较时:
左边是可选枚举值(比如.some(.inactive)),右边是普通枚举值(.inactive),二者类型不一致,自然所有判断都会返回false。
你写的self.animator.state == .none本质是判断可选值是否为空,和UIViewPropertyAnimator.State的枚举case无关,该枚举本身没有none这个case。

2. 动画无法重启、completion不触发的原因

UIViewPropertyAnimator默认行为下,动画自然完成后会自动进入inactive状态,同时会清理所有已添加的动画块、completion回调,就算你此时状态判断正确,调用startAnimation()也没有可执行的内容,自然不会触发回调。

解决方案

第一步:修正状态判断逻辑

访问状态前先解包可选值,避免可选类型带来的判断误差:

guard let animator = self.animator else { return }
print(animator.state == .active)
print(animator.state == .inactive)
print(animator.state == .stopped)

第二步:实现动画重复执行

有两种可选方案,按需选择:

  • 方案1(兼容性最好,无系统版本要求):每次需要执行动画时,重新创建UIViewPropertyAnimator实例,重新添加动画块和completion回调,每次新实例的状态都是初始的inactive,调用startAnimation()必然生效。
  • 方案2(复用实例,iOS 11+支持):初始化animator时设置pausesOnCompletion = true,开启该配置后动画完成不会自动进入inactive状态,也不会清理已添加的内容,只会暂停在完成位置,重置进度后即可重新执行:
// 初始化配置
self.animator = UIViewPropertyAnimator(duration: 1, curve: .linear)
self.animator?.pausesOnCompletion = true
self.animator?.addAnimations(someAnimationBlock)

// 加[weak self]避免循环引用
self.animator?.addCompletion{ [weak self] position in
    guard let self = self, let animator = self.animator else { return }
    switch position {
    case .end:
        print("is end")
        // 重置动画进度到起始点
        animator.fractionComplete = 0
        // 启动动画
        animator.startAnimation()
    case .start:
        print("is start")
    case .current:
        print("is current")
    @unknown default:
        break
    }
}

self.animator?.startAnimation()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 13:57:04