如何将Lottie动画指定帧的UIView转为UIImage?解决空白问题
问题
在单元格中使用LottieAnimation,通过滑块切换动画当前帧,想要将指定帧保存为UIImage并存储到用户相册。使用LottieAnimation的snapshotView方法获取对应帧的UIView,但转成UIImage时得到空白图片,求解决办法。
用户提供的代码
保存帧的方法
func saveCurrentShotFrame() { guard let shotFrameImage = animationView.snapshotView(afterScreenUpdates: false)?.asImage() else { return } delegate?.cellDidSaveShotFrameImage(shotFrameImage) }
UIView扩展
extension UIView { func asImage() -> UIImage { let renderer = UIGraphicsImageRenderer(bounds: bounds) return renderer.image { rendererContext in layer.render(in: rendererContext.cgContext) } } }
解决方案
原因分析
snapshotView返回的是视图的轻量级屏幕快照副本,当动画视图不在屏幕可视区域(如单元格复用、未完成渲染),或者afterScreenUpdates设为false导致帧未更新时,这个副本可能没有实际内容,转成UIImage就会空白。
解决方法
方法1:直接对原动画视图进行快照
放弃使用snapshotView,直接对animationView本身调用快照方法,同时确保视图已更新到当前帧:
func saveCurrentShotFrame() { // 强制刷新视图,确保当前帧完成渲染 animationView.setNeedsDisplay() animationView.layoutIfNeeded() let shotFrameImage = animationView.asImage() delegate?.cellDidSaveShotFrameImage(shotFrameImage) }
方法2:使用Lottie原生API获取帧图像(推荐)
Lottie提供了直接从动画数据渲染指定帧为UIImage的方法,无需依赖视图的屏幕渲染,结果更稳定:
func saveCurrentShotFrame() { guard let currentFrame = animationView.currentFrame, let shotFrameImage = animationView.image(fromFrame: currentFrame, size: animationView.bounds.size) else { return } delegate?.cellDidSaveShotFrameImage(shotFrameImage) }
注意事项
- 如果使用方法1,确保
animationView的isHidden为false,且其所在的单元格当前处于可视状态,否则图层渲染可能仍会失败。 - 方法2适用于Lottie 3.0及以上版本,若使用旧版本可替换为
animationView.image(forFrame:)方法。
内容的提问来源于stack exchange,提问作者Togosling
相关产品推荐
相关产品推荐

