【SwiftUI】NavigationLinkを使わない画面遷移(NavigationStack・iOS16)

SwiftUI

NavigationLinkを使わない画面遷移についてです。
iOS16以降はNavigationStackを使う事でNavigationLinkを使用しない事もできます。

NavigationViewではNavigationLinkが必須だった為、
他に遷移のトリガーを用意しても何処かに置いておく必要がありました。

パターン1

NavigationStackはnavigationDestinationに遷移先のViewを指定します。
つまりnavigationDestinationさえ動けば良いのです。

navigationDestinationにはisPresented引数があります。
ここにBoolの@State変数を渡せばOKです。

struct NavigationStackActiveView: View {
    
    @State var isPresented = false
    
    var body: some View {
        NavigationStack {
            List {
                //不要              
//                NavigationLink("Next View", value: "Not Use").onTapGesture {
//                    isPresented.toggle()
//                }
            }.navigationDestination(isPresented: $isPresented) {
                Text("SecondView")
            }
            Button("Go to SecondView"){
                isPresented.toggle()
            }
        }
    }
}

この様にNavigationLinkなしでも画面遷移が可能です。
1点注意が必要なのは、この形式で使用するとNavigationLinkのvalueが使えません。
NavigationLinkと併用する場合はonTapGestureでisPresentedを切り替えて下さい。

NavigationStackで遷移先がnavigationDestinationに分離したことによってこのような利点も生まれました。
NavigationViewでは必ずNavigationLinkに遷移先を指定しないといけない為こうは行きませんでした。

パターン2

NavigationStackのpath引数を使うパターンです。

このpathは遷移先のvalueが格納されます。
NavigationLinkをタップする事でも格納されますが、
別途ボタンや別な操作をトリガーにしてpathを変化させても画面遷移します。
その為、NavigationLinkは不要です。

こちらに関しては通常の使用感と余り変わらないと思います。
もちろんNavigationPathを使用しても同様です。

struct NavigationStackControlView: View {
    
    @State var path = [String]()
    
    var body: some View {
        NavigationStack(path:$path) {
            List {
                //不要
//                NavigationLink("Next View", value: "SecondView")
            }.navigationDestination(for: String.self) { text in
                VStack {
                    Text("Value:\(text)")
                }
            }.toolbar {
                ToolbarItemGroup(placement: .bottomBar) {
                    Button("Go to SecondView"){
                        path.append("SecondView")
                    }
                    
                    Button("Go to OtherView"){
                        path.append("OtherView")
                    }
                }
            }
        }
    }
}

最後に

NavigationStackはnavigationDestinationを使うようになった事により、
NavigationLink無しでも動作が可能になりました。

NavigationLinkのラベルを設定する事で十分な場合も多いですが、
NavigationLinkを置きたくない場合にも対応できる様になり便利になりました。

NavigationStackについての解説記事もあるので、もし良ければご覧ください。

コメント

タイトルとURLをコピーしました