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についての解説記事もあるので、もし良ければご覧ください。
コメント