SwiftUIでGIF動画を再生する! KingfisherのKFAnimatedImageの使い方
ウェブから取得した画像をキャッシュして表示するためのライブラリはいくつかある。その中でも特に有名なのが「SDWebImage」と「Kingfisher」だろう。
SDWebImageはObjective-Cプロジェクトでも使いやすく、Swiftが主流になった後も主にSDWebImageを使ってきた。SDWebImageは、カスタマイズ性が高く、少し無理な要件にも対応できるノウハウがあったからだ。
しかし、現職で開発しているアプリではKingfisherが採用されており、この1年ほどKingfisherを使う機会が増えた。Kingfisherはシンプルで使いやすい反面、特に日本語の情報が少なく、手探りで進める必要があった。公式ドキュメントにもSwiftUIでのGIF再生の具体例が少なく、特にSwiftUIでの実装例は見つからなかった。
そこで、この記事では、Kingfisherが提供する「KFAnimatedImage」を使い、SwiftUIでGIF動画(アニメーションGIF)を再生する方法を解説する。また、GIF動画を扱う際の注意点やカスタマイズ方法についても触れる。
検証環境
この記事で使用した環境は以下の通り。
- Xcode 16.2 (16C5032a)
- iOS 18.2 シミュレータ
Kingfisherの導入
まず、プロジェクトにKingfisherを導入する。Swift Package Manager(SPM)を使用するのが最も簡単だ。
Xcodeのメニューから「File」 -> 「Swift Packages」 -> 「Add Package Dependency」の順に選択する。
右上の検索欄に、リポジトリURLとして https://github.com/onevcat/Kingfisher.git
を入力する。リストから「kingfisher」を選択し、バージョン指定で「Up to Next Major」を選択する。
バージョンは「8.1.3」を指定する。このバージョンは最新の安定版である。最後に、右下の「Add Package」ボタンをクリックする。
追加するターゲットを確認し、右下の「Add Package」ボタンをクリックする。
これでKingfisherがプロジェクトに追加された。次に、基本的な使い方を確認してみる。
Kingfisherの基本的な使い方
Kingfisherを使えば、ウェブ上の画像を簡単に表示できる。以下は、SwiftUIでKingfisherを使って画像を表示する基本的な例だ。このコードでは、画像が一度ダウンロードされるとキャッシュに保存され、次回以降はネットワークアクセスなしで表示される。
import Kingfisher
import SwiftUI
struct ContentView: View {
let url = URL(string: "https://raw.githubusercontent.com/onevcat/Kingfisher/master/images/logo.png")!
var body: some View {
VStack {
KFImage(url)
.resizable()
.scaledToFit()
}
.padding()
}
}
このコードでは、KFImage
を使って指定したURLの画像を表示している。resizable()
や scaledToFit()
を組み合わせることで、画像のサイズや表示方法を柔軟に調整している。また、画像の読み込みに失敗した場合は、placeholderモディファイアを使って代替画像を表示することができる。
GIF動画を再生する
静止画として表示される問題
KFImage
を使ってGIF動画を表示しようとすると、デフォルトでは最初のフレームが「静止画」として表示されてしまう。以下のコードを例に見てみる。
struct ContentView: View {
let url = URL(string: "http://localhost:3000/img/sample.gif")!
var body: some View {
VStack {
KFImage(url)
.resizable()
.scaledToFit()
}
.padding()
}
}
このコードではGIF動画が再生されず、最初のフレームだけが静止画として表示される。GIF動画を再生するには、KFImage
ではなく専用の KFAnimatedImage
を使う必要がある。KFImageは静的な画像を扱うためのコンポーネントであり、アニメーションGIFには対応していない。一方、KFAnimatedImageはGIFなどのアニメーション画像を再生するために設計されている。
KFAnimatedImageを使ったGIF動画の再生
KFAnimatedImage
を使うと、GIF動画を簡単に再生できる。以下はその基本的な例だ。
struct ContentView: View {
let url = URL(string: "http://localhost:3000/img/sample.gif")!
var body: some View {
VStack {
KFAnimatedImage(url)
.scaledToFit()
}
.padding()
}
}
このコードでは、KFAnimatedImage
を使うことでGIF動画が正しく再生されるようになる。scaledToFit()
を使えば、動画のアスペクト比を保ちながら表示領域に収めることができる。
大きなGIFファイルを扱う場合、読み込みに時間がかかることがあるため、適切なサイズのGIFを使用することを推奨する。
GIF動画の再生回数を制御する
デフォルトでは repeatCount = .infinite
に相当しており、GIF動画は無限ループで再生されるが、再生回数を制御したい場合もある。KFAnimatedImage
では、内部的に使用されている AnimatedImageView
を直接操作することで各種設定値をカスタマイズできる。本記事では再生回数の変更について紹介するが、再生回数以外にも、アニメーション速度や背景色などをカスタマイズできる。
以下のコードは、configure
モディファイアを使って AnimatedImageView
にアクセスし、再生回数を設定する例だ。
KFAnimatedImage(url)
.configure { view in
view.repeatCount = .finite(count: 3) // 3回再生
}
.scaledToFit()
repeatCount
プロパティには以下のような値を指定できる。
.once
: 1回だけ再生する。.finite(count: UInt)
: 指定した回数だけ再生する(例:.finite(count: 10)
で10回再生)。.infinite
: 無限に再生する(デフォルト)。.finite(count: 0)
: 再生しない(静止画として表示)。
以下に具体的な例を示す。
無限ループで再生する
エンドレスで再生し続ける。
KFAnimatedImage(url)
.configure { view in
view.repeatCount = .infinite
}
.scaledToFit()
1回だけ再生する
一度再生して、その後アニメーションを停止する。
KFAnimatedImage(url)
.configure { view in
view.repeatCount = .once
}
.scaledToFit()
指定回数再生する
たとえば、10回再生したい場合は以下のようにする。
KFAnimatedImage(url)
.configure { view in
view.repeatCount = .finite(count: 10)
}
.scaledToFit()
再生しない(静止画として表示する)
GIF動画を静止画として表示したい場合は、再生回数を0回に設定する。
KFAnimatedImage(url)
.configure { view in
view.repeatCount = .finite(count: 0)
}
.scaledToFit()
まとめ
KingfisherのKFAnimatedImage
を使うと、SwiftUIでGIF動画を簡単に再生できる。また、configure
モディファイアを使えば、再生回数や細かい挙動を柔軟にカスタマイズできる。
GIF動画を扱う際は、KFImage
とKFAnimatedImage
の違いを理解し、適切に使い分けることが大切だ。例えば、アプリ内でローディングアニメーションを表示する場合は、KFAnimatedImage
が便利だろう。再生回数の制御や静止画としての表示など、ユースケースに応じた設定が可能なので、ぜひプロジェクトで活用してみてほしい。