Created
April 17, 2024 17:43
-
-
Save chockenberry/476ef4d8b1bfc73872dda8e0d9d8f49f to your computer and use it in GitHub Desktop.
NavigationPath Experiments
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// ContentView.swift | |
// NavigationTest | |
// | |
// Created by Craig Hockenberry on 4/16/24. | |
// | |
import SwiftUI | |
struct OddView: View { | |
@Binding var path: NavigationPath | |
//@Binding var path: [PathOptions] | |
var body: some View { | |
Form { | |
Section { | |
NavigationLink("Foo", value: "Foo Value") | |
NavigationLink("PIN", value: 1337) | |
NavigationLink("Pathless", value: PathOptions.pathless) | |
NavigationLink("First", value: PathOptions.first) | |
NavigationLink("Second", value: PathOptions.second) | |
NavigationLink("Third", value: PathOptions.third) | |
NavigationLink("Fourth", value: PathOptions.fourth) | |
NavigationLink("Fifth", value: PathOptions.fifth) | |
Button("Remove Last") { | |
path.removeLast() | |
} | |
Button("Back to Root") { | |
path.removeLast(path.count) | |
} | |
} | |
// NOTE: Disables selection completely. Not good. | |
//.listRowBackground(Color(UIColor.systemBackground)) | |
} | |
.formStyle(.grouped) | |
.onAppear { | |
print("OddView: path.count = \(path.count)") | |
} | |
} | |
} | |
struct EvenView: View { | |
@Binding var path: NavigationPath | |
//@Binding var path: [PathOptions] | |
var body: some View { | |
Form { | |
Section { | |
NavigationLink("Bar", value: "Bar Value") | |
NavigationLink("PUNK", value: 999) | |
NavigationLink("Pathless", value: PathOptions.pathless) | |
NavigationLink("First", value: PathOptions.first) | |
NavigationLink("Second", value: PathOptions.second) | |
NavigationLink("Third", value: PathOptions.third) | |
NavigationLink("Fourth", value: PathOptions.fourth) | |
NavigationLink("Fifth", value: PathOptions.fifth) | |
Button("Remove Last") { | |
path.removeLast() | |
} | |
Button("Append First") { | |
path.append(PathOptions.first) | |
} | |
} | |
} | |
.formStyle(.grouped) | |
.onAppear { | |
print("EvenView: path.count = \(path.count)") | |
} | |
} | |
} | |
struct PathlessView: View { | |
var body: some View { | |
Form { | |
Section { | |
NavigationLink("First", value: PathOptions.first) | |
NavigationLink("Second", value: PathOptions.second) | |
NavigationLink("Pathless", value: PathOptions.pathless) | |
} | |
} | |
.formStyle(.grouped) | |
.onAppear { | |
print("PathlessView: no path binding") | |
} | |
} | |
} | |
enum PathOptions: String { | |
case first | |
case second | |
case third | |
case fourth | |
case fifth | |
case pathless | |
} | |
struct ContentView: View { | |
@State private var path = NavigationPath() | |
//@State private var path = [PathOptions.first, PathOptions.second] | |
var body: some View { | |
NavigationStack(path: $path) { | |
Form { | |
Section { | |
NavigationLink("First", value: PathOptions.first) | |
NavigationLink("Second", value: PathOptions.second) | |
} | |
} | |
.formStyle(.grouped) | |
.navigationTitle("ContentView") | |
.navigationDestination(for: PathOptions.self) { pathOption in | |
switch pathOption { | |
case .first: | |
OddView(path: $path) | |
.navigationTitle("First") | |
case .second: | |
EvenView(path: $path) | |
.navigationTitle("Second") | |
case .third: | |
OddView(path: $path) | |
.navigationTitle("Third") | |
case .fourth: | |
EvenView(path: $path) | |
.navigationTitle("Fourth") | |
case .fifth: | |
OddView(path: $path) | |
.navigationTitle("Fifth") | |
case .pathless: | |
PathlessView() | |
.navigationTitle("Pathless") | |
} | |
} | |
.navigationDestination(for: String.self) { string in | |
Text("View with '\(string)'") | |
.navigationTitle(string) | |
} | |
.navigationDestination(for: Int.self) { int in | |
Text("View with \(int)") | |
.navigationTitle("\(int)") | |
} | |
.onAppear { | |
print("ContentView: path = \(path.count)") | |
} | |
} | |
} | |
} | |
#Preview { | |
ContentView() | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
The issue is that the row values for the
NavigationLink
are used to determine identity (they must beHashable
). When you have a cyclical graph, you need something else to make the row unique. One option is to add a "level" to the items you add to theNavigationPath
:https://gist.github.com/phillipcaudell/fda686d67bde2f87a9252fbd802fcc3a
This causes the hash value for the row to be unique, even if the underlying data is not.