在 UIView 中动画图像

Animating images in a UIView

我有一个由 SwiftUI 提供的 UIViewRepresentable 视图,我在其中创建了三个或四个相当复杂的图形对象,并以精确的速度在视图中移动它们。我使用 CADisplayLink 来计算这些对象对于每个新帧应该移动多少。

我的帧速率不是很好,所以我想我会尝试通过以编程方式创建 UIImage 并将其缓存在主内存中来缓存图像块。这很好用,我可以在单独的线程中创建新的 UIImage 对象,但帧速率实际上比只按需要绘制所有内容要慢一些。

视图包含三四个这样的东西,我有一个后台任务创建不久的将来需要的UIIMages,并重新使用已经滚出屏幕的UIImages,所以我的内存利用率相对较小 - 如有必要,我可以创建一个大的合成图像,它只是使用 ScrollView 以编程方式滚动,但我担心这种方法会使用更多的内存。

有没有更好的方法来缓存视图的可重用块并在整个视图中为它们设置动画?当然,我想尽可能多地卸载到 GPU。创建 UIImage 是正确的方法吗?创建 CALayer 或其他一些位图表示会更好吗?我应该把这些东西放到一个 ScrollView 中吗?我应该创建一个可以由系统动画的视图,而不是使用 CADisplayLink 计时逐帧动画吗? (我需要能够在接到通知后立即取消动画)。

我明白这可能不是一个只有一个正确答案的简单代码问题,但我希望能朝着正确的方向推动,谢谢!

Apple 开发了多种框架,每种框架都可能是此应用程序的合适选择。软件设计人员的重要选择之一是 select 适合特定应用程序的框架。

Apple 倾向于记录单个框架而不讨论它们与其他框架的关系,这就是为什么我认为在 select 构建架构时咨询整个开发社区很有价值。

在这种情况下,一些位图表示缓存在主内存中,一些缓存在显卡的显存中(仅Mac OS),一些缓存在移动设备的后备存储中一个视图。从 Apple 的文档中并不总是很明显特定的 class 是如何实际实现的。

因此,我对几种不同的方法进行了基准测试(当然是对相同的内容进行动画处理):

  • 在内存中创建一个 UIImage 对象数组,并通过 CADisplayLink 绘制它们产生大约 6 Hz 的帧速率。
  • 创建一个 CALayer 并使用 CADisplayLink 对其进行定位产生了 120 Hz 的帧速率。

我不声称知道 UIImage 光栅化是如何处理的,但我猜测它是使用主 CPU 处理器和主内存发生的,并且图像被复制到显存中主绘图循环。很明显,其中一些任务被传递给了 Metal,但实际上它是如何实现的并不明显。

我猜测 CALayers 被认为不需要缩放和光栅化,并且视口更改由 GPU 处理,几乎没有 CPU 干预。

我仍然不知道我是否最好开始动画并在必要时调整它,或者明确定位 CALayer 是否最好。但是我使用的方法产生了良好的帧速率和低 CPU 使用率,所以我将把它作为学术问题留给 reader.

我发现了一些关于该主题的有用文章:

https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/CoreAnimation_guide/CoreAnimationBasics/CoreAnimationBasics.html#//apple_ref/doc/uid/TP40004514-CH2-SW3

https://blog.spacemanlabs.com/2011/07/calayers-v-cglayers-or-which-layer-player/

add UIImage in CALayer

https://www.raywenderlich.com/10317653-calayer-tutorial-for-ios-getting-started