如何在视图被表视图回收时保持 Lottie 动画 运行?

How to keep a Lottie animation running when the view is recycled by a tableview?

我有一个 UITableView 有很多不同的自定义单元格,其中 1 个有 Lottie 动画视图,当我按下按钮或接收某些网络消息时,动画应该跳转到特定的 position/progress 然后向前或向后设置动画。

到目前为止,一切都很好,所有这些都正常工作,直到我向下滚动并且 UITableViewCell 被回收,这停止了我的动画并且我失去了正确的 position/progress.

我考虑过可能使用计时器并尝试将其与动画进度同步,或者实例化一个隐藏的 LottieAnimationView 并将其与可见的同步。有人处理过这个问题吗?

这是一个相当长的变长动画(通常在 20 到 30 秒之间)Curtain/Door,需要在多个设备之间同步,每当幕布变化时,服务器都会向每个客户端发送一条消息方向,消息包括方向(打开、关闭或停止)及其位置(0% 到 100%(关闭到打开)的百分比)。

动画连接的是一个真实的设备,一个窗帘,是那个设备的反馈,这就是网络调用的目的,所以它不会循环。根据房间的不同,可能有 2 到 4 个带有动画的单元格,每个单元格和动画对应不同的窗帘,还有十几个或更多的单元格有 0 个动画并且完全不相关。每个单元格存储一个唯一的 ID、窗帘的最后一个动作、窗帘最后接收到的 0% 到 100% 之间的位置以及动画的持续时间和速度。

加载页面时,内容全部从 XML 文件中读取。然后我使用 TCP 通信来更改开关、按钮和滑块的状态。像这样:https://imgur.com/L5M5mki

有什么建议吗?

首先,您应该知道哪个单元格是您的动画单元格,并且您不应该使该单元格出列。您将在控制器中创建该单元格,这样动画单元格将永远不会从您的 UITableView.

重新初始化
    let animationCell = AnimationCell()

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
       if indexPath.row == 0 { //0 is the animation cell
         return animationCell
        } else { 
         // try to dequeue your regular cell
        }
    }

另一种方法即使您有很多单元要出列和重用也可以使用:

在某处保存一个 static/global 字典或缓存,然后在调用 tableView:didEndDisplaying: 时将 animationView.realtimeAnimationProgress 存储在那里。

然后在 tableView:willDisplay: 中,您可以将该值分配回 animationView.currentProgress,然后使用您最初播放的任何原始结束状态调用 play(toProgress:)

这样即使在新的单元格中动画也可以恢复。如果您有一个复杂的用例,只需存储其他信息,例如原始所需的结束状态和循环行为。您可能还需要存储当前的实际时间,以调整进度,无论动画被冻结后经过了多少 real-world 时间,如果动画已经滚出屏幕并且您希望它返回,就好像时间已经过去一样被及时冻结。