【SwiftUI】インストール後だけ起動するイントロ画面を作りたい

# 概要
- よくある、インストール後だけに出てくる「ようこそ！」みたいな画面を作りたかった。
- `@AppStrage`と`switch`文を活用することで実現できた。

# 環境
- macOS: 13.0.1
- iOS: 16.1
- XCode: 14.1

# 完成品
画質荒いですが、以下の順で、`Next>`を押すたび切り替わっていることがわかります。
（本当はスライドみたいなオシャレなアニメーションをつけたかった）
1. イントロ1画面
1. イントロ2画面
1. イントロ3画面
1. アプリホーム画面
1. <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2918864/5e2be92f-6eec-c825-09df-3ca6a8cac64f.gif" width=300>

# ソースコード全文
## GitHub
https://github.com/dachscafe/InitialViewSample

## 全文解説

1. 以下、`InitialView()`の設定です。`@AppStrage`に**初回起動フラグ**、`@State`に**ページ番号**を定義することで、これらの数値が変わったときに、switch文が対応するページに振り分けてくれます。

    ```swift: InitialView.swift(上部)
    import SwiftUI

    struct InitialView: View {
        
        @AppStorage("is_init") var isInit = true    // 初回画面フラグ
        @State var page: Int = 1                    // ページ番号
        
        var body: some View {
            if isInit {
                switch page {
                case 1:
                    Intro1View(page: $page)
                case 2:
                    Intro2View(page: $page)
                case 3:
                    Intro3View(page: $page)
                default:
                    ContentView()
                }
            } else {
                ContentView()
            }
        }
    }
    // 下に続く

    ```
1. 次に、イントロ画面たちの設定です。ボタンを押すと、`page`の値を更新したり、`Intro3View()`の画面で`@AppStrage`に保存している`isInit`を`false`にしています。
（`@AppStrage`はアプリを削除しない限り端末に保存され続けるので、一度falseになったら更新しない限り残り続けます。ちなみに`= true`は初期値の定義です）

    ```swift: InitialView.swift(続き)
    // 続き
    struct Intro1View: View {
        
        @Binding var page: Int
        
        var body: some View {
            ZStack{
                Color.yellow
                    .ignoresSafeArea()
                VStack {
                    Text("Intro1")
                    Button("Next >") {
                        withAnimation(){
                            page = 2
                        }
                    }
                    .padding()
                } // HStack
            } // ZStack
        }
    }
    
    struct Intro2View: View {
        
        @Binding var page: Int
        
        var body: some View {
            ZStack{
                Color.green
                    .ignoresSafeArea()
                VStack {
                    Text("Intro2")
                    HStack{
                        Button("< Back") {
                            withAnimation(){
                                page = 1
                            }
                        }
                        Button("Next >") {
                            withAnimation(){
                                page = 3
                            }
                        }
                    } // HStack
                    .padding()
                } // VStack
            }  // ZStack
        }
    }
    struct Intro3View: View {
        
        @Binding var page: Int
        @AppStorage("is_init") var isInit = true    // 初回画面フラグ
        
        var body: some View {
            ZStack{
                Color.mint
                    .ignoresSafeArea()
                VStack {
                    Text("Intro3")
                    HStack{
                        Button("< Back") {
                            withAnimation(){
                                page = 2
                            }
                        }
                        Button("Start!") {
                            withAnimation(){
                                isInit = false  // 二度とtrueに戻せなくなる
                                page = 1
                            }
                        }
                    } // HStack
                    .padding()
                } // VStack
            }  // ZStack
        }
    }
    ```


1. Appには、`ContentView()`ではなく`InitialView()`を設定します。
    ``` swift:InitialViewSampleApp.swift
    import SwiftUI
    
    @main
    struct InitialViewSampleApp: App {
        var body: some Scene {
            WindowGroup {
                InitialView()
            }
        }
    }
    ```
1. おまけで、最後に`ContentView()`です。一応、デバッグ用に初期画面からも`isInit`を`true`に戻せるようにしてます。

    ```swift:ContentView.swift
    import SwiftUI
    
    struct ContentView: View {
        
        @AppStorage("is_init") var isInit = true    // 初回起動フラグ
        
        var body: some View {
            VStack {
                Text("アプリのホーム画面")
                Button("初回起動フラグ立て直し"){
                    isInit = true
                }
                .padding()
            }
        }
    }
    
    ```
1. 以上


# 参考
- AppStgageについて：　https://www.yururiwork.net/archives/1310