ChatGPTのレクチャーは有料級!iPhoneアプリの画面遷移方法について教えてもらった(swiftUI, navigationDestination)
日々ChatGPTにSwiftUIをレクチャーをしてもらっています!
最近はお勉強用にクイズアプリを作っていますが、画面遷移周りを色々いじってたら、想定通りに動かず、NavigationStackや、navigationDestinationの仕組みがよくわからなかったので、ChatGPTに簡単な画面遷移パターンをベースに仕様を教えてもらおうと思います!
前回までのswiftUIでのアプリ開発
1.NavigationStackや、navigationDestinationを使用した画面遷移について、ChatGPTに教えてもらう
1-1.教えてもらう画面遷移パターンについて
1-2.ChatGPTの回答
import SwiftUI
struct ContentView: View {
@State private var path = NavigationPath()
var body: some View {
NavigationStack(path: $path) {
ViewZ(path: $path)
.navigationDestination(for: String.self) { view in
switch view {
case "ViewA":
ViewA(path: $path)
case "ViewB":
ViewB(path: $path)
case "ViewC":
ViewC(path: $path)
default:
Text("Unknown View")
}
}
}
}
}
struct ViewZ: View {
@Binding var path: NavigationPath
var body: some View {
VStack {
Text("This is View Z")
Button(action: {
path.append("ViewA")
}) {
Text("Go to View A")
}
}
}
}
struct ViewA: View {
@Binding var path: NavigationPath
var body: some View {
VStack {
Text("This is View A")
Button(action: {
path.append("ViewB")
}) {
Text("Go to View B")
}
}
}
}
struct ViewB: View {
@Binding var path: NavigationPath
var body: some View {
VStack {
Text("This is View B")
Button(action: {
path.append("ViewC")
}) {
Text("Go to View C")
}
}
}
}
struct ViewC: View {
@Binding var path: NavigationPath
var body: some View {
VStack {
Text("This is View C")
Button(action: {
// Clear the path to return to ViewA
path.removeLast(path.count)
path.append("ViewA")
}) {
Text("Go to View A")
}
}
}
}
@main
struct YourApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
2.ContentViewのロジック詳細
それでは詳細のロジックを見ていきます!
ContentViewのロジックが、ナビゲーション遷移を管理する基点となり、ここで遷移のルールを決めて、あとは各種viewでここのcase文箇所の遷移先を設定すれば遷移できるイメージとなります。
struct ContentView: View {
@State private var path = NavigationPath()
var body: some View {
NavigationStack(path: $path) {
ViewZ(path: $path)
.navigationDestination(for: String.self) { view in
switch view {
case "ViewA":
ViewA(path: $path)
case "ViewB":
ViewB(path: $path)
case "ViewC":
ViewC(path: $path)
default:
Text("Unknown View")
}
}
}
}
}
2-1.ContentViewで、NavigationStackを使用しビュー間の遷移を管理
2-2.@State private var path = NavigationPath()
2-3.NavigationStack(path: $path)
2-4.最初に表示したいビューをpathをバインドして設定する
2-5.navigationDestination(for: String.self) { view in ... }
2-6.switch view { ... }:view
3.各種Viewのロジックについて
ContentViewで遷移先ロジックを実装しましたが、使用する側はContentViewで定義したcase文の遷移先を、pathにappendするイメージとなります。
3-1.ContentViewの遷移先設定箇所
switch view {
case "ViewA":
ViewA(path: $path)
case "ViewB":
ViewB(path: $path)
case "ViewC":
ViewC(path: $path)
3-2.使用する側はpath.appendするだけ
struct ViewZ: View {
@Binding var path: NavigationPath
var body: some View {
VStack {
Text("This is View Z")
Button(action: {
path.append("ViewA")
}) {
Text("Go to View A")
}
}
}
}
3-3.@Binding var path: NavigationPath
3-4.path.append("ViewA")
4.viewCからviewAに遷移するロジック
viewCからviewAに遷移するロジックは上記パターンとは少々異なり、一度path(ナビゲーションの履歴管理)をリセットした後に、pathにviewAを設定するロジックとなります。
4-1.path.removeLast(path.count):
4-2.path.append("ViewA"):
5.ナビゲーションパスをクリアする利点について
5-1.特定の状態に戻れるため、ユーザー体験を簡略化できる
5-2.メモリ等のパフォーマンス観点
6.pathをリセットする場合としない場合の挙動について
pathをリセットする場合としない場合とで、「戻るボタン」について動作確認してみることにしました。
6-1.pathをリセットするロジックを使用した場合の戻るボタンの挙動
上記のロジックでの戻るボタンの挙動は以下。
ナビゲーション履歴がリセットされるので、以下グレー色の遷移履歴が削除されるイメージとなりました。
6-2.pathをリセットしないロジックを使用した場合の戻るボタンの挙動
ロジックの変更箇所は、以下リセット処理を削除したのみで、
path.removeLast(path.count)
戻るボタンの挙動を確認すると、通常通り遷移した順で戻れました。
おわりに
最後まで読んでいただき、ありがとうございます!
サーバーサイドのGET遷移のように簡単にできるのかなと思っていましたが、仕組みが全然違うので理解するのに少々苦労しました、、
NavigationPathや、navigationDestinationの処理イメージは、だいぶついてきましたので、あとは自分の作りたいアプリの画面遷移を設計し、どのタイミングでリセットするか?などを適宜検討していく必要がありそうです。
アドリブで作っていくと混乱しそうなので、事前に画面フローは整理しておく必要がありそうですね、、
遷移の仕方は今回のパターン以外にもありますので、その他の遷移パターンも今後整理していきたいと思います。
おまけ
最近、ChatGPTを使用し、色々なことを模索しています。
もしよければ、以下の記事も見て頂けると嬉しいです!
この記事が気に入ったらサポートをしてみませんか?