Swift & SwiftUIでタロットカードアプリを作る

# はじめに
Swiftの学習を兼ねて、簡単なタロットカードアプリを作ってみました。
今回は画像を使わず、文字だけで作ります。

Xcodeが必要なので、環境はmacOSです。
（私のMacが古いので、今と違うところがあるかもしれません）

# 要件
 - 起動したら「カードを引く」ボタンを表示
 - ボタンをタップしたらタロットカードをランダムに表示
 - 「もう一度引く」ボタンで再度タロットカードをランダムに表示

# 準備
### Xcodeプロジェクトの作成
1. Xcodeを起動し、新しいプロジェクトを作成します
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407770/8cca0991-25c0-f457-f3bd-3df3c7ed2dc9.png" width="90%" />

2. "App"テンプレートを選択し、"Next"をクリックします
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407770/bcb28a01-f42a-6902-c380-a63393dfbfa6.png" width="90%" />

3. プロジェクト名に「TarotApp」などを入力し、インターフェースは「SwiftUI」を選択します
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407770/7c01d6c3-2004-72c3-1eae-648b3a888ed9.png" width="90%" />


4. 作業フォルダを選択し、「Create」でプロジェクトを作成します
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407770/be38bd08-4ef9-a6f5-9a53-9c278e2d1f1e.png" width="90%" />

5. プロジェクトが作成されました！
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407770/7d6150a1-c8e9-b978-b11f-63d5fac30b02.png" width="90%" />


### 今回のディレクトリ構成
`CardView`と`TarotCards`を追加してます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407770/a02b8abc-90b1-294e-3d60-783bcfd8b356.png" width="60%" />

# 実装
コンテンツ本体
```swift:ContentView.swift
//
//  ContentView.swift
//  TarotApp
//

import SwiftUI

struct ContentView: View {
    @State private var selectedCard: TarotCard?

    var body: some View {
        NavigationView {
            VStack(spacing: 20) {
                Text("TarotApp")
                    .font(.largeTitle)
                    .fontWeight(.bold)
                    .padding()
                    .frame(maxWidth: .infinity) // タイトルを中央寄せにする
                    .background(Color.gray.opacity(0.2))
                    .cornerRadius(10)

                if let card = selectedCard {
                    CardView(card: card)
                    Button("もう一度引く") {
                        // ランダムにカードを選択
                        selectedCard = tarotCards.randomElement()
                    }
                    .padding()
                    .background(Color.blue)
                    .foregroundColor(.white)
                    .cornerRadius(10)
                } else {
                    Button("カードを引く") {
                        // ランダムにカードを選択
                        selectedCard = tarotCards.randomElement()
                    }
                    .padding()
                    .background(Color.blue)
                    .foregroundColor(.white)
                    .cornerRadius(10)
                }
            }
            .navigationTitle("TarotApp")
            .navigationBarTitleDisplayMode(.inline) // タイトルを中央寄せにする
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}
```
カード表示部分
```swift:CardView.swift
//
//  CardView.swift
//  TarotApp
//

import SwiftUI

struct CardView: View {
  let card: TarotCard

  var body: some View {
    VStack(spacing: 10) {
      Text(card.name)
        .font(.largeTitle)
        .fontWeight(.bold)
        .padding()
        .background(Color.gray.opacity(0.2))
        .cornerRadius(10)

      Text(card.description)
        .font(.headline)
        .multilineTextAlignment(.center)
        .padding()

      Spacer()

      Text("意味")
        .font(.title2)
        .fontWeight(.bold)
        .padding()
      
      Text(card.meaning)
        .font(.body)
        .padding()
    }
    .padding()
    .background(Color(UIColor.systemGray6))
    .cornerRadius(20)
    .shadow(radius: 5)
  }
}
```

カードの配列
Gemini 1.5 Flashに、一気に（10秒くらいで）作ってもらいました。
内容は精査してませんが、一旦このまま使います。
```swift:TarotCards.swift
//
//  TarotCards.swift
//  TarotApp
//

import SwiftUI

struct TarotCard: Identifiable {
  let id = UUID()
  let name: String
  let description: String
  let meaning: String
}

let tarotCards: [TarotCard] = [
  TarotCard(name: "The Fool",
            description: "始まり、無邪気さ、新しい旅立ち",
            meaning: "新しい章の始まり、自由な精神、冒険心"),
  TarotCard(name: "The Magician",
            description: "意志力、創造力、潜在能力",
            meaning: "目標達成、能力発揮、潜在能力の開花"),
  TarotCard(name: "The High Priestess",
            description: "直感、神秘、秘密",
            meaning: "内なる知恵、直感力、秘密の解明"),
  TarotCard(name: "The Empress",
            description: "豊穣、愛情、自然",
            meaning: "豊かさ、愛情、創造性"),
  TarotCard(name: "The Emperor",
            description: "権力、安定、秩序",
            meaning: "安定、統率力、権威"),
  TarotCard(name: "The Hierophant",
            description: "伝統、信仰、精神的指導",
            meaning: "伝統、精神的な指導、社会規範"),
  TarotCard(name: "The Lovers",
            description: "愛、調和、選択",
            meaning: "愛情、調和、パートナーシップ"),
  TarotCard(name: "The Chariot",
            description: "意志、勝利、克服",
            meaning: "意志力、目標達成、克服"),
  TarotCard(name: "Strength",
            description: "強さ、勇気、忍耐",
            meaning: "内なる強さ、克服、忍耐"),
  TarotCard(name: "The Hermit",
            description: "内省、孤独、自己探求",
            meaning: "内観、自己成長、探求"),
  TarotCard(name: "Wheel of Fortune",
            description: "運命、変化、サイクル",
            meaning: "運命、変化、サイクル"),
  TarotCard(name: "Justice",
            description: "公正、均衡、法則",
            meaning: "公正、バランス、調和"),
  TarotCard(name: "The Hanged Man",
            description: "犠牲、視点を変える、新しい見方",
            meaning: "新しい視点、見直し、変化"),
  TarotCard(name: "Death",
            description: "終わり、変容、再生",
            meaning: "終わりと始まり、変容、再生"),
  TarotCard(name: "Temperance",
            description: "調和、バランス、忍耐",
            meaning: "バランス、調和、忍耐"),
  TarotCard(name: "The Devil",
            description: "誘惑、執着、物質主義",
            meaning: "誘惑、執着、依存"),
  TarotCard(name: "The Tower",
            description: "破壊、変化、混乱",
            meaning: "破壊、変革、混乱"),
  TarotCard(name: "The Star",
            description: "希望、再生、癒し",
            meaning: "希望、再生、癒し"),
  TarotCard(name: "The Moon",
            description: "幻想、直感、隠された真実",
            meaning: "幻想、直感、隠された真実"),
  TarotCard(name: "The Sun",
            description: "喜び、成功、幸福",
            meaning: "喜び、成功、幸福"),
  TarotCard(name: "Judgement",
            description: "再生、自己評価、新しい始まり",
            meaning: "再生、自己評価、新しい始まり"),
  TarotCard(name: "The World",
            description: "完成、達成、統合",
            meaning: "完成、達成、統合"),
  TarotCard(name: "The Major Arcana",
            description: "運命のサイクル、人生の旅路",
            meaning: "人生の重要な課題、試練"),
  TarotCard(name: "Ace of Wands",
            description: "新しい始まり、情熱、創造性",
            meaning: "新しいプロジェクト、情熱、創造性"),
  TarotCard(name: "Two of Wands",
            description: "計画、展望、決断",
            meaning: "計画、展望、決断"),
  TarotCard(name: "Three of Wands",
            description: "拡大、成長、冒険",
            meaning: "拡大、成長、冒険"),
  TarotCard(name: "Four of Wands",
            description: "安定、祝賀、達成",
            meaning: "安定、祝賀、達成"),
  TarotCard(name: "Five of Wands",
            description: "競争、対立、混乱",
            meaning: "競争、対立、混乱"),
  TarotCard(name: "Six of Wands",
            description: "成功、勝利、栄光",
            meaning: "成功、勝利、栄光"),
  TarotCard(name: "Seven of Wands",
            description: "防衛、抵抗、忍耐",
            meaning: "防衛、抵抗、忍耐"),
  TarotCard(name: "Eight of Wands",
            description: "動き、変化、スピード",
            meaning: "動き、変化、スピード"),
  TarotCard(name: "Nine of Wands",
            description: "忍耐、決意、防衛",
            meaning: "忍耐、決意、防衛"),
  TarotCard(name: "Ten of Wands",
            description: "負担、責任、完成",
            meaning: "負担、責任、完成"),
  TarotCard(name: "Page of Wands",
            description: "新しいアイデア、熱意、探検",
            meaning: "新しいアイデア、熱意、探検"),
  TarotCard(name: "Knight of Wands",
            description: "行動力、情熱、冒険心",
            meaning: "行動力、情熱、冒険心"),
  TarotCard(name: "Queen of Wands",
            description: "独立心、自信、創造性",
            meaning: "独立心、自信、創造性"),
  TarotCard(name: "King of Wands",
            description: "リーダーシップ、成功、野心",
            meaning: "リーダーシップ、成功、野心"),
  TarotCard(name: "Ace of Cups",
            description: "愛情、感情、創造性",
            meaning: "愛情、感情、創造性"),
  TarotCard(name: "Two of Cups",
            description: "調和、愛情、パートナーシップ",
            meaning: "調和、愛情、パートナーシップ"),
  TarotCard(name: "Three of Cups",
            description: "祝賀、友情、喜び",
            meaning: "祝賀、友情、喜び"),
  TarotCard(name: "Four of Cups",
            description: "内省、満足、孤独",
            meaning: "内省、満足、孤独"),
  TarotCard(name: "Five of Cups",
            description: "悲しみ、喪失、失望",
            meaning: "悲しみ、喪失、失望"),
  TarotCard(name: "Six of Cups",
            description: "過去、思い出、ノスタルジア",
            meaning: "過去、思い出、ノスタルジア"),
  TarotCard(name: "Seven of Cups",
            description: "幻想、誘惑、選択",
            meaning: "幻想、誘惑、選択"),
  TarotCard(name: "Eight of Cups",
            description: "離脱、失望、新しい出発",
            meaning: "離脱、失望、新しい出発"),
  TarotCard(name: "Nine of Cups",
            description: "満足、幸福、願いの成就",
            meaning: "満足、幸福、願いの成就"),
  TarotCard(name: "Ten of Cups",
            description: "完璧な幸福、家庭、愛",
            meaning: "完璧な幸福、家庭、愛"),
  TarotCard(name: "Page of Cups",
            description: "新しい愛、感情、創造性",
            meaning: "新しい愛、感情、創造性"),
  TarotCard(name: "Knight of Cups",
            description: "ロマンチック、夢、理想",
            meaning: "ロマンチック、夢、理想"),
  TarotCard(name: "Queen of Cups",
            description: "共感、慈悲、直感",
            meaning: "共感、慈悲、直感"),
  TarotCard(name: "King of Cups",
            description: "感情の支配、感情の安定、調和",
            meaning: "感情の支配、感情の安定、調和"),
  TarotCard(name: "Ace of Swords",
            description: "新しいアイデア、決断、突破",
            meaning: "新しいアイデア、決断、突破"),
  TarotCard(name: "Two of Swords",
            description: "停滞、決断の遅延、葛藤",
            meaning: "停滞、決断の遅延、葛藤"),
  TarotCard(name: "Three of Swords",
            description: "悲しみ、失恋、苦痛",
            meaning: "悲しみ、失恋、苦痛"),
  TarotCard(name: "Four of Swords",
            description: "休息、回復、静寂",
            meaning: "休息、回復、静寂"),
  TarotCard(name: "Five of Swords",
            description: "敗北、裏切り、争い",
            meaning: "敗北、裏切り、争い"),
  TarotCard(name: "Six of Swords",
            description: "移転、旅立ち、癒し",
            meaning: "移転、旅立ち、癒し"),
  TarotCard(name: "Seven of Swords",
            description: "裏切り、詐欺、隠蔽",
            meaning: "裏切り、詐欺、隠蔽"),
  TarotCard(name: "Eight of Swords",
            description: "制限、束縛、囚われ",
            meaning: "制限、束縛、囚われ"),
  TarotCard(name: "Nine of Swords",
            description: "不安、恐怖、悪夢",
            meaning: "不安、恐怖、悪夢"),
  TarotCard(name: "Ten of Swords",
            description: "破壊、敗北、絶望",
            meaning: "破壊、敗北、絶望"),
  TarotCard(name: "Page of Swords",
            description: "知性、メッセージ、情報",
            meaning: "知性、メッセージ、情報"),
  TarotCard(name: "Knight of Swords",
            description: "迅速な行動、攻撃性、決断力",
            meaning: "迅速な行動、攻撃性、決断力"),
  TarotCard(name: "Queen of Swords",
            description: "独立心、知性、冷静",
            meaning: "独立心、知性、冷静"),
  TarotCard(name: "King of Swords",
            description: "権威、支配、正義",
            meaning: "権威、支配、正義"),
  TarotCard(name: "Ace of Pentacles",
            description: "豊かさ、財産、新しい始まり",
            meaning: "豊かさ、財産、新しい始まり"),
  TarotCard(name: "Two of Pentacles",
            description: "バランス、多忙、調整",
            meaning: "バランス、多忙、調整"),
  TarotCard(name: "Three of Pentacles",
            description: "チームワーク、職人技、協力",
            meaning: "チームワーク、職人技、協力"),
  TarotCard(name: "Four of Pentacles",
            description: "安全、安定、所有",
            meaning: "安全、安定、所有"),
  TarotCard(name: "Five of Pentacles",
            description: "貧困、失業、孤独",
            meaning: "貧困、失業、孤独"),
  TarotCard(name: "Six of Pentacles",
            description: "慈善、寛大、共有",
            meaning: "慈善、寛大、共有"),
  TarotCard(name: "Seven of Pentacles",
            description: "努力、辛抱、成果",
            meaning: "努力、辛抱、成果"),
  TarotCard(name: "Eight of Pentacles",
            description: "技能、熟練、努力",
            meaning: "技能、熟練、努力"),
  TarotCard(name: "Nine of Pentacles",
            description: "成功、豊かさ、満足",
            meaning: "成功、豊かさ、満足"),
  TarotCard(name: "Ten of Pentacles",
            description: "遺産、財産、家族",
            meaning: "遺産、財産、家族"),
  TarotCard(name: "Page of Pentacles",
            description: "新しい機会、学習、潜在能力",
            meaning: "新しい機会、学習、潜在能力"),
  TarotCard(name: "Knight of Pentacles",
            description: "勤勉、責任、安定",
            meaning: "勤勉、責任、安定"),
  TarotCard(name: "Queen of Pentacles",
            description: "豊穣、実用性、安定",
            meaning: "豊穣、実用性、安定"),
  TarotCard(name: "King of Pentacles",
            description: "富、成功、物質的な豊かさ",
            meaning: "富、成功、物質的な豊かさ")
]

```

# 動作確認
まずはContentViewで確認。
「カードを引く」ボタンを押します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407770/c6473f3e-2435-1fc8-411a-c843d487b44b.png" width="90%" />

『The Devil』が表示されました！

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407770/277f58db-9078-8b79-3854-67ca3e72f9e6.png" width="90%" />

続いて、シミュレーターを起動して確認します。
「カードを引く」ボタンを押します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407770/e22b7361-e210-7943-81d9-8046bc3b1551.png" width="60%" />

『Queen of Swords』が表示されました！

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407770/1a189673-f358-7fca-c82c-bc5ae03df716.png" width="60%" />

続いて、「もう一度引く」ボタンを押すと、
『The Magician』が表示されました！

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407770/39540118-8c24-b52c-bcd0-743166984744.png" width="60%" />

うまく動きましたね！
タロットカードの画像を用意しておけば、より本格的になりそうです。

# まとめ
今回は、簡易的なタロットカードアプリを作ってみました。
まだまだ改良の余地があるので、また別の機会にチャレンジしてみようと思います。

みなさんも一緒にがんばりましょう🙂