在UIView中对图像进行动画处理

时间:2020-07-05 23:37:32

标签: ios swift animation uiimage swiftui

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

我的帧速率不是很出色,所以我认为我将尝试通过以编程方式创建UIImage并将其缓存在主内存中来缓存图像块。这足够好,我可以在单独的线程中创建新的UIImage对象,但是帧速率实际上比仅绘制所需的东西慢一些。

该视图包含其中的三四个内容,并且我有一个后台任务,该任务创建在不久的将来将需要的UIIMages,并重新使用滚动到屏幕之外的UIImage,因此我的内存利用率相对较高最小-如有必要,我可以创建一个大的合成图像,只需使用ScrollView以编程方式对其进行滚动,但我担心这种方法会占用更多的内存。

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

我很欣赏这可能不是一个只有正确答案的简单代码问题,但我希望朝着正确的方向前进,谢谢!

1 个答案:

答案 0 :(得分:0)

Apple已经开发了各种框架,每种框架都可能是此应用程序的合适选择。对于软件设计人员来说,重要的选择之一就是为特定的应用程序选择适当的框架。

Apple倾向于在不讨论各个框架与其他框架的关系的情况下记录单个框架,这就是为什么我认为在选择一个体系结构时咨询整个开发社区很有价值。

在这种情况下,某些位图表示会缓存在主内存中,有些会缓存在图形卡的视频内存(仅适用于Mac OS)中,有些会缓存在移动设备的后备存储中以供查看。从Apple的文档中,并不总是很明显如何实际实现特定的类。

因此,我对几种不同的方法进行了基准测试(当然,它们使内容相同):

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

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

我猜想认为CALayers不需要缩放和栅格化,并且视口更改是由GPU处理的,而CPU干预很少。

我仍然不知道我是否最好开始动画并在必要时对其进行调整,或者明确定位CALayer是否最佳。但是我使用的方法可以产生良好的帧速率和较低的CPU使用率,因此我会将其作为学术问题留给读者。

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

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