为什么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
相关产品推荐
相关产品推荐

