You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 06:30:07