'SwiftUI display gif image
The way to display animated gif image in swiftUI
because of Image
Image("fall-leaves")
does not support gifs
answer below
Solution 1:[1]
Easiest and fastest way to display gif image in swiftUI - is to use Preview
/ QuickLook (QL)
/ QLPreviewView
Quartz available only in 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
}
Solution 2:[2]
I was having a hard time using this in my macOS app because I try to load my gif file from the local assets rather than a URL. After looking around for answers, the best answer seems to be putting the gif file into the project folder rather than into the Assets.xcassets and then load the resource into the URL. Somehow Bundle.main.url(forResource: myFile, withExtension: "gif") will return nil if the file isn't in the main project folder. I checked the ProjectName -> Target -> Build Phases -> Copy Bundle Resources and the gif file is there automatically when I add to the project. The weird thing is somehow the gif file is not available if it's in the Assets.xcassets.
I updated the QLImage struct from @Andrew to load the gif file by name (make sure to add the gif directly to your project as mentioned above). Here's the updated code below. You need to also provide a sample gif image called preview-gif or call it whatever you want and match the name in the preview section.
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")
}
}
This will return a view, but you need to specify the frame size or you can't see anything. Use it like this it a view:
QLImage("myGif").frame(width: 500, height: 300, alignment: .center)
Set whatever frame size is appropriate. All the other view-related properties are also available with this.
Hope this helps somebody else who is trying to display GIF images from local resources on macOS. Apple should really make it easier to display animated GIF since it's being used everywhere these days.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | Patratacus |