In the code below when i press on a NavigationLink
to go to a HeroView
, I get an unexpected result. The view is temporarily added and then removed. When i go back from the HeroList
to go to ContentView
, it navigates to the HeroView
i expected to reach from clicking on a hero in the HeroList
View.
The example code below recreates this problem. Any help would be greatly appreciated.
struct ContentView: View {
var body: some View {
NavigationStack {
NavigationLink("Click here to see the list of heroes") {
HeroList()
}
}
}
}
struct HeroList: View {
@State private var heroes: [Hero] = [Hero(id: 0, name: "Hercules"), Hero(id: 1, name: "Superman")]
var body: some View {
ScrollView {
ForEach(heroes, id:\.id) { hero in
NavigationLink(value: hero) {
// Problem happens when the navigation link is pressed
Text("Find out more about: \(hero.name)")
.padding(.bottom)
}
}
}
.navigationDestination(for: Hero.self) { hero in
HeroView(hero: hero)
}
}
}
struct HeroView: View {
@ObservedObject var hero: Hero
var body: some View {
Text(hero.name)
.font(.title)
}
}
// Custom Hero type
class Hero: Identifiable, Hashable, ObservableObject {
let id: Int
var name: String
init(id: Int, name: String) {
self.id = id
self.name = name
}
static func == (lhs: Hero, rhs: Hero) -> Bool {
return ObjectIdentifier(lhs) == ObjectIdentifier(rhs)
}
func hash(into hasher: inout Hasher) {
hasher.combine(ObjectIdentifier(self))
}
}
Try this approach using two navigationDestination
, one for the HeroList()
and another one for the HeroView(...)
. Also simplified the struct Hero
:
struct ContentView: View {
var body: some View {
NavigationStack {
NavigationLink(value: "HeroList") {
Text("Click here to see the list of heroes")
}
.navigationDestination(for: String.self) { _ in // <-- here
HeroList()
}
}
}
}
struct HeroList: View {
@State private var heroes: [Hero] = [Hero(id: 0, name: "Hercules"), Hero(id: 1, name: "Superman")]
var body: some View {
ScrollView {
ForEach(heroes) { hero in
NavigationLink(value: hero) {
Text("Find out more about: \(hero.name)")
.padding(.bottom)
}
}
}
.navigationDestination(for: Hero.self) { hero in
HeroView(hero: hero)
}
}
}
struct HeroView: View {
var hero: Hero // <-- here
var body: some View {
Text("-----HeroView-----")
Text(hero.name).font(.title)
}
}
struct Hero: Identifiable, Hashable { // <-- here
let id: Int
var name: String
}