Open2

TabView + NavigationStack でタップ時にルートに戻るようにする

まったまった
// MainTabView.swift
import SwiftUI

struct MainTabView: View {
    @State private var selection = 0
    @State var path = NavigationPath()

    var body: some View {
        // 一度この proxy を経由させないと onChange(of: selection, perform:)  では同じタブのタップ時に検知できない
        let proxySelection = Binding<Int> {
            selection
        } set: {
            selection = $0
            if selection == 0 {
                path = NavigationPath() // path.removeLast(path.count) でもいいはず
            }
        }

        TabView(selection: proxySelection) { // いずれかのタブがタップされると proxySelection の set 関数が呼ばれる
            BookCollectionView(user: user)
                .onAppear {
                    selection = 0
                }
                .tabItem {
                    Image(systemName: "character.book.closed")
                    Text("図鑑")
                }
                .tag(0)
        }
        .tint(.primary)
    }
}
// BookView.swift
import SwiftUI

struct BookView: View {
    @Binding private var path: NavigationPath

    init(path: Binding<NavigationPath>) {
        self._path = path // @Binding  の場合、アンダースコアを先頭につけないといけないっぽい
    }

    var body: some View {
        NavigationStack(path: $path) {
            Button {
                self.path.append("BookDetailView") // path は [String] でなく専用の型を作ったほうがよい
            } label: {
                Text("詳細ページへ")
            }
            .navigationDestination(for: String.self, destination: { _ in
                    BookDetailView()
            })
        }
    }
}

もともとは.id(randomId)を使ってタップのたびに UUID() で生成したIDをここに入れてViewを作り直す?方法が Stack Overflow で紹介されていたが、対象タブが NavigationStack を持っているとクラッシュしたり、子Viewへのプッシュ遷移が行われなくなるなどの挙動があったし、何よりタップの度に別 id として生成し直すのもモヤッとしたので。

まったまった

タブの tag 名を enum で定義してもダメだったし、また参考文献にある onRecieve(publisher: $selection, action:) としても駄目だった。.onTapGesture() は独自で selection を変更する処理などを書いたりするようのカスタムメソッドっぽかったのでこれも止めた。
https://developer.apple.com/documentation/swiftui/navigationpath
https://qiita.com/ohka_madhatter/items/ce706d3fd26e58a74b7a
https://dev.classmethod.jp/articles/swiftui-tabview-select/
https://qiita.com/yoshi-eng/items/91666637cd7cdd8edf88