SwiftUI 显示 gif 图片

SwiftUI display gif image

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") 将以某种方式 return 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")
    }
}

这将 return 一个视图,但您需要指定框架大小,否则您将看不到任何内容。像这样使用它的视图:

 QLImage("myGif").frame(width: 500, height: 300, alignment: .center)

设置合适的帧大小。所有其他 view-related 属性也可用于此。

希望这对尝试在 macOS 上显示来自本地资源的 GIF 图像的其他人有所帮助。 Apple 真的应该让显示动画 GIF 变得更容易,因为现在到处都在使用它。