swiftUI中显示动画gif图片的方法
因为图像
Image("fall-leaves")
不支持gif
回答如下
在 swiftUI 中显示 gif 图像的最简单、最快的方法 - 是使用
Preview
/ QuickLook (QL)
/ QLPreviewView
Quartz 仅在 macOS 10.4+ 中可用 https://developer.apple.com/documentation/quartz
import SwiftUI
import Quartz
struct QLImage: NSViewRepresentable {
var url: URL
func makeNSView(context: NSViewRepresentableContext<QLImage>) -> QLPreviewView {
let preview = QLPreviewView(frame: .zero, style: .normal)
preview?.autostarts = true
preview?.previewItem = url as QLPreviewItem
return preview ?? QLPreviewView()
}
func updateNSView(_ nsView: QLPreviewView, context: NSViewRepresentableContext<QLImage>) {
nsView.previewItem = url as QLPreviewItem
}
typealias NSViewType = QLPreviewView
}
我在 macOS 应用程序中使用此功能时遇到了困难,因为我尝试从本地资源而不是 URL 加载 gif 文件。在寻找答案后,最好的答案似乎是将 gif 文件放入项目文件夹而不是放入 Assets.xcassets,然后将资源加载到 URL 中。如果文件不在主项目文件夹中,那么 Bundle.main.url(forResource: myFile, withExtension: "gif") 将返回 nil 。我检查了 ProjectName -> Target -> Build Phases -> Copy Bundle Resources,当我添加到项目时,gif 文件会自动存在。奇怪的是,如果 gif 文件位于 Assets.xcassets 中,则它不可用。
我更新了 @Andrew 的 QLImage 结构,以按名称加载 gif 文件(确保如上所述将 gif 直接添加到您的项目中)。下面是更新后的代码。您还需要提供一个名为 Preview-gif 的示例 gif 图像,或者将其命名为任何您想要的名称并与预览部分中的名称相匹配。
import SwiftUI
import Quartz
struct QLImage: NSViewRepresentable {
private let name: String
init(_ name: String) {
self.name = name
}
func makeNSView(context: NSViewRepresentableContext<QLImage>) -> QLPreviewView {
guard let url = Bundle.main.url(forResource: name, withExtension: "gif")
else {
let _ = print("Cannot get image \(name)")
return QLPreviewView()
}
let preview = QLPreviewView(frame: .zero, style: .normal)
preview?.autostarts = true
preview?.previewItem = url as QLPreviewItem
return preview ?? QLPreviewView()
}
func updateNSView(_ nsView: QLPreviewView, context: NSViewRepresentableContext<QLImage>) {
guard let url = Bundle.main.url(forResource: name, withExtension: "gif")
else {
let _ = print("Cannot get image \(name)")
return
}
nsView.previewItem = url as QLPreviewItem
}
typealias NSViewType = QLPreviewView
}
struct QLImage_Previews: PreviewProvider {
static var previews: some View {
QLImage("preview-gif")
}
}
这将返回一个视图,但您需要指定框架大小,否则您将看不到任何内容。像这样使用它:
QLImage("myGif").frame(width: 500, height: 300, alignment: .center)
设置合适的框架尺寸。所有其他与视图相关的属性也可用于此。
希望这可以帮助其他尝试在 macOS 上显示本地资源中的 GIF 图像的人。 Apple 确实应该让显示动画 GIF 变得更容易,因为现在它已经随处可见。
它定义了一个符合 UIViewRepresentable 的 GifImageView 结构体,允许我们使用 WKWebView 来显示 GIF。
GifImageView 将 GIF 图像名称作为参数。 在 makeUIView 内部,它创建一个 WKWebView,加载 GIF 数据并显示它。
updateUIView 函数确保视图在需要时重新加载。 要使用此 GifImageView,只需在 SwiftUI 视图层次结构中创建一个实例,如 ContentView 中所示。您可以根据需要随意调整框架尺寸(宽度和高度)以适合您的用户界面
import SwiftUI
import WebKit
enum URLType {
case name(String)
case url(URL)
var url: URL? {
switch self {
case .name(let name):
return Bundle.main.url(forResource: name, withExtension: "gif")
case .url(let remoteURL):
return remoteURL
}
}
}
struct GifImageView: UIViewRepresentable {
private let name: String
init(_ name: String) {
self.name = name
}
func makeUIView(context: Context) -> WKWebView {
let webview = WKWebView()
let url = Bundle.main.url(forResource: name, withExtension: "gif")!
let data = try! Data(contentsOf: url)
webview.load(data,mimeType: "image/gif",characterEncodingName: "UTF-8", baseURL: url.deletingLastPathComponent())
return webview
}
func updateUIView(_ uiView: WKWebView, context: Context) {
uiView.reload()
}
}