画像付きのSwiftUIでバンドルを使用する方法

Aug 18 2020

例:プロジェクトにバンドルがあります。これは「Game.Bundle」と呼ばれます。

let b :Bundle = Bundle.init(path: Bundle.main.path(forResource:"Game", ofType:"bundle")!)!
Image("Giyuu",bundle:self.b)

しかし、バンドルは機能しません。

カスタムバンドルを使用するにはどうすればよいですか

回答

1 Asperi Aug 18 2020 at 23:09

SwiftUIImage(_ , bundle: _)は、対応するバンドルのアセットカタログで画像リソースを検索します。あなたの場合、画像は通常のファイルとして埋め込まれているだけなので、ファイルとして見つけてロードする必要があります。Imageそれ自体はそれを行うことができないので、そのUIImageような可能性があるもので構築する必要があります。

したがって、メインバンドルのサブフォルダーにいると仮定するGame.bundlePlugIns(そうでない場合は、以下の対応するパスの構築を修正するだけです)、ここで可能なアプローチがあります。

Xcode 12 / iOS14でテスト済み

struct ContentView: View {
    var body: some View {
        Image(uiImage: gameImage(name: "test") ?? UIImage())
    }

    func gameImage(name: String, type: String = "png") -> UIImage? {
        guard let plugins = Bundle.main.builtInPlugInsPath,
              let bundle = Bundle(url: URL(fileURLWithPath:
                           plugins).appendingPathComponent("Game.bundle")),
              let path = bundle.path(forResource: name, ofType: type)
              else { return nil }
        return UIImage(contentsOfFile: path)
    }
}
1 WarrenBurton Aug 18 2020 at 22:42

提供されているスニペットは、インスタンスとしてもローカル変数としてbも参照しselfているようです

let b :Bundle = Bundle.init(path: Bundle.main.path(forResource:"Game", ofType:"bundle")!)!
Image("Giyuu",bundle:self.b)

よかったですか?

let bundle :Bundle = Bundle.init(path: Bundle.main.path(forResource:"Game", ofType:"bundle")!)!
let image = Image("Giyuu",bundle:bundle)

Or refactored to eliminate force unwraps ! with some problem analysis added.

func getGiyuuImage() -> Image {
    guard let path = Bundle.main.path(forResource:"Game", ofType:"bundle"), let bundle = Bundle(path: path) else {
        fatalError("dev error - no Game bundle")
    }
    let image = Image("Giyuu",bundle: bundle)
    return image
}