【Xcode/SwiftUI】Navigation遷移で一気にトップ画面に戻る方法


プロジェクトの構成


NavigationManagerの構成

import SwiftUI

class NavigationManager: ObservableObject {
    @Published var path: [ShowView] = []
}

enum ShowView: Hashable {
    case secondView
    case thirdView
    case forthView
    case fifthView
}

(アプリ名).swiftファイル内に以下を追記しておく

import SwiftUI

@main
struct SwiftUILabApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
                .environmentObject(NavigationManager()) // 追記
        }
    }
}

各Viewの構成

import SwiftUI

struct ContentView: View {
    @EnvironmentObject var navigationModel: NavigationManager // 遷移フラグ
    
    var body: some View {
        NavigationStack(path: $navigationModel.path) {
            VStack {
                Image(systemName: "car")
                    .resizable()
                    .scaledToFit()
                    .frame(width: UIScreen.main.bounds.width / 10)
                Button {
                    navigationModel.path.append(.secondView)
                } label: {
                    Text("スタート")
                        .font(.largeTitle)
                        .padding()
                }
            }
            .navigationDestination(for: ShowView.self) { showView in
                switch showView {
                case .secondView:
                    SecondView()
                case .thirdView:
                    ThirdView()
                case .forthView:
                    ForthView()
                case .fifthView:
                    FifthView()
                }
            }
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
            .environmentObject(NavigationManager())
    }
}
import SwiftUI

struct <#何番目の#>View: View {
    @EnvironmentObject var navigationModel: NavigationManager // 遷移フラグ
    
    var body: some View {
        VStack {
            Image(systemName: "<#SFSymbolsの画像名#>")
                .resizable()
                .scaledToFit()
                .frame(width: UIScreen.main.bounds.width / 10)
            Button {
                navigationModel.path.append(.<#遷移先の#>View)
            } label: {
                Text("<#遷移先の#>Viewへ")
                    .font(.largeTitle)
                    .padding()
            }
        }
        .navigationBarBackButtonHidden(true)
    }
}

struct <#何番目の#>View_Previews: PreviewProvider {
    static var previews: some View {
        <#何番目の#>View()
            .environmentObject(NavigationManager())
    }
}
import SwiftUI

struct FifthView: View {
    @EnvironmentObject var navigationModel: NavigationManager
    
    var body: some View {
        VStack {
            Image(systemName: "bag")
                .resizable()
                .scaledToFit()
                .frame(width: UIScreen.main.bounds.width / 10)
            Button {
                navigationModel.path.removeAll()
            } label: {
                Text("トップに戻る")
                    .font(.largeTitle)
                    .padding()
            }
            .navigationBarBackButtonHidden(true)
        }
    }
}

struct FifthView_Previews: PreviewProvider {
    static var previews: some View {
        FifthView()
    }
}

SwiftUIはまだまだ知識が足りない、もっと勉強しよう、、、