我有一组本地UIImage
,我需要加载它们并在按下它们各自的单元格时按顺序显示。例如,我有20张热狗的图像组合在一起形成一个动画。当用户点击热狗单元格时,单元格的UIImageView
应该为图像设置动画。
我知道如何使用UIImageView
的{{1}}来实现动画效果。我的问题是从磁盘检索所有这些图像大约需要1.5秒并阻塞主线程。
我可以在animationImages
中实例化一个帮助器类,它在后台线程上从磁盘加载这些图像,这样它们在需要时就会在内存中,但这看起来很糟糕。
有没有更好的方法可以快速从磁盘加载许多图像?
编辑:这些图片是插图,因此是.png。
Edit2:假设每个图像序列的总和为1 MB。我正在测试的图像尺寸比application(_:didFinishLaunchingWithOptions:)
的@ 3x要求大33-60%。在我们的设计师获得正确的图像集之前,我是等待确认最终的UIImageView
大小,所以应该使用适当大小的资产显着缩短时间,但我也在物理iPhone上进行测试X
UIImageView
答案 0 :(得分:1)
我建议您尝试UIImage(contentsOfFile:)
而不是UIImage(named:)
。在我的快速测试中发现它快了一个数量级。这有点可以理解,因为它做了很多事情(搜索资产,缓存资产等)。
// slow
@IBAction func didTapNamed(_ sender: Any) {
let start = CFAbsoluteTimeGetCurrent()
imageView.animationImages = (0 ..< 20).map {
UIImage(named: filename(for: $0))!
}
imageView.animationDuration = 1.0
imageView.animationRepeatCount = 1
imageView.startAnimating()
print(CFAbsoluteTimeGetCurrent() - start)
}
// faster
@IBAction func didTapBundle(_ sender: Any) {
let start = CFAbsoluteTimeGetCurrent()
let url = Bundle.main.resourceURL!
imageView.animationImages = (0 ..< 20).map {
UIImage(contentsOfFile: url.appendingPathComponent(filename(for: $0)).path)!
}
imageView.animationDuration = 1.0
imageView.animationRepeatCount = 1
imageView.startAnimating()
print(CFAbsoluteTimeGetCurrent() - start)
}
请注意,这假定您拥有资源目录中的文件,并且您可能必须根据它们在项目中的位置进行相应的修改。另请注意,我避免在循环中执行Bundle.main.url(forResource:withExtension:)
,因为即使这样做也会对性能产生可观察的影响。