2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【SwiftUI】GIFを表示したい

Last updated at Posted at 2024-02-03

はじめに

SwiftUIでGIFを使いたかったので使えるようにGIFViewを作ってみました。

サンプルアプリ

Simulator Screen Recording - iPhone 15 - 2024-02-03 at 22.40.41.gif

今回使用するGIF

heart.gif

SuperGSATBによるPixabayのGIF

実装

import SwiftUI

struct GIFView: View {
    @State private var images: [Image] = []
    @State private var gifCount: Int = 0
    @State private var currentIndex: Int = 0

    var gifName: String
    var minimumInterval: Double
    
    var body: some View {
        TimelineView(.animation(minimumInterval: minimumInterval)) { context in
            Group {
                if images.isEmpty {
                    Text("エラー")
                } else {
                    images[currentIndex]
                        .resizable()
                        .scaledToFit()
                }
            }
            .onChange(of: context.date) {
                if currentIndex == (gifCount - 1) {
                    currentIndex = 0
                } else {
                    currentIndex += 1
                }
            }
        }
        .onAppear {
            guard let bundleURL = Bundle.main.url(forResource: gifName, withExtension: "gif"),
                  let gifData = try? Data(contentsOf: bundleURL),
                  let source = CGImageSourceCreateWithData(gifData as CFData, nil)
            else {
                return
            }
            gifCount = CGImageSourceGetCount(source)
            var cgImages: [CGImage?] = []
            for i in 0..<gifCount {
                cgImages.append(CGImageSourceCreateImageAtIndex(source, i, nil))
            }
            let uiImages = cgImages.compactMap({ $0 }).map({ UIImage(cgImage: $0) })
            images = uiImages.map({ Image(uiImage: $0) })
        }
    }
}

使い方

使用したいGIFをXcodeにドラッグします。
スクリーンショット 2024-02-03 22.42.56.png

以下の設定で「Finish」を押します。
スクリーンショット 2024-02-03 22.43.40.png

使用側では、
gifNameはGIFのファイル名、
minimumIntervalはGIFの1枚の画像にかける秒数
を渡します。

import SwiftUI

struct ContentView: View {
    var body: some View {
        GIFView(gifName: "Heart", minimumInterval: 0.03)
            .frame(width: 300, height: 300)
    }
}

おわり

ロジック部分はもうちょいいい感じにできそうです。
currentIndexで表示画像を管理しているのをもうちょい改善したいです。

改善案があれば編集リクエストがコメントください!

追記(2024/2/8)

コメントで教えてもらったもっと表示方法です!!

参考コード

2
2
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?