วิธีใช้ Bundle ใน SwiftUI กับ Image

Aug 18 2020

ตัวอย่างเช่นฉันมี Bundle ในโปรเจ็กต์เรียกว่า "Game.Bundle"

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

แต่ Bundle ไม่ทำงาน

ฉันจะใช้ Bundle แบบกำหนดเองได้อย่างไร

คำตอบ

1 Asperi Aug 18 2020 at 23:09

SwiftUI Image(_ , bundle: _)ค้นหาทรัพยากรรูปภาพในแค็ตตาล็อก Assets ของกลุ่มที่เกี่ยวข้อง ในกรณีของคุณรูปภาพถูกฝังเป็นไฟล์ปกติดังนั้นคุณต้องค้นหาและโหลดเป็นไฟล์ Imageตัวมันเองไม่สามารถทำเช่นนั้นได้ดังนั้นจึงควรสร้างขึ้นโดยUIImageมีความเป็นไปได้ดังกล่าว

ดังนั้นสมมติว่าคุณGame.bundleอยู่ในPlugInsโฟลเดอร์ย่อยของกลุ่มหลัก (ถ้าไม่ใช่ - เพียงแก้ไขการสร้างเส้นทางที่เกี่ยวข้องด้านล่าง) นี่เป็นแนวทางที่เป็นไปได้

ทดสอบด้วย Xcode 12 / iOS 14

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)

หรือ refactored เพื่อกำจัดแรงคลาย!ด้วยการวิเคราะห์ปัญหาบางอย่างที่เพิ่มเข้ามา

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
}