在 SwiftUI 中,原生不支持直接显示 GIF 动画:
Image("gif0") // 不显示图片
可以考虑以下三种常见方案。
常见方案
1、使用WebView实现GIF
利用 WKWebView 显示本地或远程 GIF,优点是实现简单,兼容性好。
import SwiftUI
import WebKit
struct GIFView: UIViewRepresentable {
let gifName: String // 文件名或 URL
func makeUIView(context: Context) -> WKWebView {
let webView = WKWebView()
webView.scrollView.isScrollEnabled = false
webView.backgroundColor = .clear
webView.isOpaque = false
if let path = Bundle.main.path(forResource: gifName, ofType: "gif") {
let url = URL(fileURLWithPath: path)
let data = try? Data(contentsOf: url)
webView.load(data!, mimeType: "image/gif", characterEncodingName: "utf-8", baseURL: url.deletingLastPathComponent())
} else if let url = URL(string: gifName) {
webView.load(URLRequest(url: url))
}
return webView
}
func updateUIView(_ uiView: WKWebView, context: Context) {}
}
SwiftUI显示:
GIFView(gifName: "gif")
.frame(width: 100, height: 100)
2、使用 UIImageView(系统级高性能)
这方法适用于 iOS 14+,用 UIKit 的 UIImage.animatedImage。
import SwiftUI
import UIKit
import ImageIO
struct AnimatedImageView: UIViewRepresentable {
let gifName: String
func makeUIView(context: Context) -> UIImageView {
let imageView = UIImageView()
imageView.contentMode = .scaleAspectFit
imageView.clipsToBounds = true
if let path = Bundle.main.path(forResource: gifName, ofType: "gif"),
let data = try? Data(contentsOf: URL(fileURLWithPath: path)),
let source = CGImageSourceCreateWithData(data as CFData, nil) {
var images: [UIImage] = []
let count = CGImageSourceGetCount(source)
for i in 0..<count {
if let cgImage = CGImageSourceCreateImageAtIndex(source, i, nil) {
images.append(UIImage(cgImage: cgImage))
}
}
let duration = Double(count) / 20.0 // 约20帧/秒
imageView.animationImages = images
imageView.animationDuration = duration
imageView.startAnimating()
}
return imageView
}
func updateUIView(_ uiView: UIImageView, context: Context) {}
}
SwiftUI显示:
AnimatedImageView(gifName: "coin_spin")
注意:UIImageView在SwiftUI中,无法使用 frame 控制图像大小。
如果本地资源多,需要更好的性能优化,可以考虑UIImageView。
3、使用SDWebImageSwiftUI
在项目中导入第三方库 SDWebImageSwiftUI:
swift package add https://github.com/SDWebImage/SDWebImageSwiftUI.git
SwiftUI显示:
import SDWebImageSwiftUI
struct ContentView: View {
var body: some View {
AnimatedImage(name: "funny_cat.gif", isAnimating: .constant(true))
.resizable()
.scaledToFit()
.frame(width: 150, height: 150)
}
}
SDWebImageSwiftUI库还可以加载远程 GIF:
AnimatedImage(url: URL(string: "https://example.com/animation.gif")!)
如果要加载网络GIF 图片,有缓存或复杂需求,可以考虑 SDWebImageSwiftUI。
总结
SwiftUI中最简单的方法是通过 WebView 显示 GIF 图片。
另外两种方法存在不能控制大小和需要第三方库的情况,需要根据实际需求而定。
