Lottie Animation:停止循环,但等到动画完成

Posted

技术标签:

【中文标题】Lottie Animation:停止循环,但等到动画完成【英文标题】:Lottie Animation: Stop Loop but wait until animation has finished 【发布时间】:2019-12-19 12:09:24 【问题描述】:

我目前正在使用 Lottie 在 Swift 中为按钮设置不同的动画。

我需要的是一种停止循环的方法,但前提是动画到达结尾并会重复。在那一刻,我希望能够加入并用另一个非循环动画替换动画,这样它看起来就像从循环动画到另一个动画的流畅过渡。这样做的原因是,我在循环动画时等待通过网络获取数据的完成。

它以相反的方式进入循环动画,如下所示:

func animate(animation: Animation?, endIn loop: Animation?) 
    self.setImage(nil, for: .normal)
    self.animationView.isHidden = false
    self.animationView.animation = animation
    self.animationView.loopMode = .playOnce
    self.animationView.play  _ in
        self.animationView.animation = loop
        self.animationView.loopMode = .loop
        self.animationView.play()
    

也许其他人已经实现了这样的转换,我将不胜感激。

编辑:我尝试过这种方式,然后在提取完成时调用self.animationView.loopMode = .playOnce

func animate(startAnimation: Animation?,
             transitionTo loop: Animation?,
             endAnimation: Animation?,
             image: UIImage?) 
    self.setImage(nil, for: .normal)
    self.animationView.isHidden = false
    self.animationView.animation = startAnimation
    self.animationView.loopMode = .playOnce
    self.animationView.play  _ in
        self.animationView.animation = loop
        self.animationView.loopMode = .loop
        self.animationView.play  _ in
            self.animationView.animation = endAnimation
            self.animationView.loopMode = .playOnce
            self.setImage(image, for: .normal)
        
    

编辑 2:

我找到了一个有效的解决方案,方法是通过上层函数启动循环,然后调用它来结束它:

func stopLoopAndTranstion(to animation: Animation?, endIn image: UIImage?) 
    guard let animation = animation else 
        return
    

    if self.animationView.realtimeAnimationProgress > 0.95 
        self.animationView.stop()
        self.animationView.animation = animation
        self.animationView.loopMode = .playOnce
        self.animationView.play()
     else 
        DispatchQueue.main.asyncAfter(deadline: .now() + 0.01) 
            self.stopLoopAndTranstion(to: animation, endIn: image)
        
    

我在这里做的是检查动画进度,一旦达到某个进度,我就会停止并替换动画。 我宁愿认为这是一个 hack 而不是解决方案。每次我触发此功能时,CPU 使用率都会增加 2-3%,直到动画被替换。 虽然这 2-3% 可以忽略不计,但我还不满意,仍在寻找更清洁的方法来实现这样的目标。

【问题讨论】:

等待动画中剩余的持续时间而不是任意时间? 【参考方案1】:

您可以使用Lottie 提供的play(fromProgress...) API 之一

animationView.play(
    fromProgress: animationView.currentProgress,
    toProgress: 1,
    loopMode: .playOnce,
    completion:  [weak self] completed in
        DispatchQueue.main.asyncAfter(deadline: .now() + 0.01) 
            self.stopLoopAndTranstion(to: animation, endIn: image)
        
    
)

这将确保您当前的动画将完成,并且您可以在 completion 块中完成您的收尾工作

【讨论】:

以上是关于Lottie Animation:停止循环,但等到动画完成的主要内容,如果未能解决你的问题,请参考以下文章

当我点击不同的标签栏项目时,Lottie 动画停止

Lottie 动画在“needsUpdate”上崩溃?

flutter 启动屏幕使用 Lottie 动画

lottie动画实战(仿汽车之家底部Tab切换动画)

lottie循环播放(代码实现)

QThread::quit() 是立即结束线程还是等到返回事件循环?