代码之家  ›  专栏  ›  技术社区  ›  Milan Nosáľ

UIViewPropertyAnimator在停止动画时未停止

  •  4
  • Milan Nosáľ  · 技术社区  · 8 年前

    我正在使用 UIViewPropertyAnimator

    致命异常:NSInternalInconsistencyException

    释放暂停或停止的特性动画制作程序是错误的。属性动画师必须完成动画制作,或者在释放之前显式停止并完成。

    由于Crashlytics并没有提供更多的上下文,我能做的就是确保我的所有动画师在 viewController 已发布。

    在我的一次尝试中,我试图确保当我创建一个新的动画师时,旧的动画师会停止并完成:

    fileprivate var runningAnimator: UIViewPropertyAnimator? {
        didSet {
            if let oldValue = oldValue {
                print(">> before stopping: \(oldValue.isRunning)")
                oldValue.stopAnimation(false)
                print(">> after stopping: \(oldValue.isRunning)")
                oldValue.finishAnimation(at: .end)
                print(">> after finishing: \(oldValue.isRunning)")
            }
        }
    }
    

    但是,现在我的应用程序开始崩溃,出现以下错误:

    “nSinternalinconsistenceexception”,原因:“finishAnimationAtPosition:只应在停止的动画师上调用!”

    在输出上打印时:

    >> before stopping: true
    >> after stopping: true
    

    所以很明显 oldValue 即使在调用之后,animator仍在运行 oldValue.stopAnimation(false) .

    这怎么可能?

    1 回复  |  直到 6 年前
        1
  •  6
  •   Milan Nosáľ    8 年前

    现在,经过一个多小时的搜索、调试和分析,我终于找到了发生这种情况的原因。我分享这篇文章,希望能帮助其他人避免落入这个陷阱。

    在创建 runningAnimator ,我添加了一个应该设置的完成块 runningAnimator运行动画师 当动画师完成时设置为零:

    runningAnimator!.addCompletion({ [unowned self] (_) in
        self.runningAnimator = nil
    })
    

    现在的问题是 didSet 部件被此完成块调用。这个 runningAnimator运行动画师 已经完成了,我想 迪德塞特 代码在完成块期间发生 oldValue.stopAnimation(false) 在完成块尚未完成之前,无法真正停止动画师。

    只是为了记录,虽然这似乎有无限递归,但这不应该发生,因为调用 stopAnimation finishAnimation 在已完成的动画上,动画师不会再次调用完成块。