新たに書き直した為、この記事ではなく以下の記事を確認してください。
iOS16/iPadOS16からはNavigationViewが非推奨(Deprecated)となりました。
代わりに実装されたのがNavigationStackです。
これに合わせてNavigationLinkにも変更がありselectionの引数があるものが非推奨になりました。画面遷移を制御するコードが大きく変わったので確認していきましょう。
NavigationStackの画面遷移
NavigationStackの準備
まずは基本となるNavigationStackを用意します。
フルーツの一覧を表示し選択したフルーツの名前が表示される簡単なNavigationStackです。
enum Fruits:String,CaseIterable {
case apple = "Apple"
case grape = "Grape"
case strawberry = "Strawberry"
}
struct FruitsListView: View {
var body: some View {
NavigationStack{
List(Fruits.allCases ,id: \.self){ fruit in
NavigationLink(fruit.rawValue, value: fruit)
}
.navigationDestination(for: Fruits.self) { fruit in
Text(fruit.rawValue)
}
.navigationTitle("FruitsList")
}
}
}
基本形
NavigationStackで画面遷移するには引数のpathを使います。
まず@Stateでpath用の変数を用意します。
ここはNavigationLinkで使用するvalueの型の『配列』にします。
次にNavigationStackに引数を追加します。Bindingなので先程@Stateで宣言した変数を$つきで渡します。
最後に遷移させるコードです。
配列に遷移先のvalueを追加することで目的の画面に遷移します。
今回は簡単にボタンを用意しました。
struct FruitsListView: View {
@State private var path: [Fruits] = [] //追加
var body: some View {
NavigationStack(path: $path){//追加
List(Fruits.allCases ,id: \.self){ fruit in
NavigationLink(fruit.rawValue, value: fruit)
}
.navigationDestination(for: Fruits.self) { fruit in
Text(fruit.rawValue)
}
.navigationTitle("FruitsList")
//追加
Button("Apple"){
path.append(.apple)
}
}
}
}
画面遷移に合わせて配列に追加/削除されるイメージです。
初期値を入れたりonAppearで入れる事で直接遷移先を表示する事も可能ですし、
配列から値を削除することで戻る事も出来ます。
複数回画面遷移する
pathは配列です。配列に複数の値を入れると複数回画面遷移します。
例えば配列が[.apple , .grape]となっていればFruitsList>Apple>Grapeといった形で画面遷移します。
配列の中身がそのまま画面遷移の順と一致する様になっています。
また、配列を空にすると一度にListまで戻る事が出来ます。
配列のindexの小さい要素だけ削除する事もできます。
上記の例であれば.appleのみを削除するとGrape画面からBackを押すとそのままListに戻ります。
struct NavigaitonControlView: View {
@State private var path: [Fruits] = []
var body: some View {
NavigationStack(path: $path){
List(Fruits.allCases ,id: \.self){ fruit in
NavigationLink(fruit.rawValue, value: fruit)
}
.navigationDestination(for: Fruits.self) { fruit in
Text(fruit.rawValue)
Button("Back to List"){//追加
path.removeAll()
}
Button("Remove at 0"){//追加
path.remove(at: 0)
}
}
.navigationTitle("FruitsList")
Button("Apple"){
path.append(.apple)
path.append(.grape)//追加
}
}
}
}
NavigationViewとの比較
ここまでの内容でNavgationViewとの比較をします。
NavgationViewの場合はNavigationLinkに全て詰め込まれています。
NavigationLinkが長くなりがちで、Viewも別なクラスや関数に分けないとネストが深くなります。
また重要な点として、NavigationViewは1つの変数につき1階層毎の管理となっています。
NavigationStackでは配列で全階層を管理することになります。
複数階層のNavgationを利用する時に大きく差が出てくる点なので注意が必要です。
struct OldNavigationControlView: View {
@State private var selection:Fruits?
var body: some View {
NavigationView{
VStack {
List(Fruits.allCases ,id: \.self){ fruit in
NavigationLink(fruit.rawValue, tag: fruit, selection: $selection) {
Text(fruit.rawValue)
Button("Back to List"){
selection = nil
}
}
}
.navigationTitle("FruitsList")
Button("Apple"){
selection = .apple
}
}
}
}
}
最後に
NavigationStackで複数階層を制御する方法は検証やコードを整える作業に時間がかかっています。
長くなると思いますので、後に別記事をして作成しリンク追加します。
追記:以下の続きは記事をご確認ください。
コメント
[…] […]