I was refactoring the Moonshot project from Hacking with iOS - SwiftUI Edition 2024-04-05 acording to the challenge #3:
"upgrade it to use NavigationLink(value:). This means adding Hashable conformance, and thinking carefully how to use navigationDestination()."
Regardless of where I add the navigationDestination it behaves same way, meaning in the preview it opens the requested view but in simulator it shows white empty view for a second and then it gets back to the root of the project.
Any suggestions what am I missing here?
Code below
//
// Moonshot.swift
import SwiftUI
struct Moonshot: View {
@State private var showingList = false
let astronauts: [String: Astronaut] = Bundle.main.decode("astronauts.json")
let missions: [Mission] = Bundle.main.decode("missions.json")
var body: some View {
Toggle(isOn: $showingList) {}
.toggleStyle(HorizontalToggleStyle())
NavigationStack {
Group {
if !showingList {
MoonshootGridLayout(astronauts: astronauts, missions: missions)
} else {
MoonshootListLayout(astronauts: astronauts, missions: missions)
}
}
.navigationTitle("Moonshot")
.padding(.bottom)
.preferredColorScheme(.dark)
}
}
}
#Preview {
Moonshot()
}
import SwiftUI
struct MoonshootListLayout: View {
let astronauts: [String: Astronaut]
let missions: [Mission]
var body: some View {
List {
ForEach(missions) { mission in
NavigationLink(value: mission) {
MoonshootListRow(mission: mission)
}
}
}
// The 3 lines below I tested in every place/class, I could think off, with same result
// (in some places I got error
// A navigationDestination for “HWSwiftUI.Mission” was declared earlier on the stack.
// Only the destination declared closest to the root view of the stack will be used.
// Type: Fault | Timestamp: 2024-06-10 09:11:29.308529+01:00 | Process: HWSwiftUI | Library: SwiftUI |
// Subsystem: com.apple.SwiftUI | Category: Invalid Configuration | TID: 0x1b0a1)
.navigationDestination(for: Mission.self) { selectedMission in
MissionView(mission: selectedMission, astronauts: astronauts
}
}
}
import SwiftUI
struct MoonshootListRow: View {
let mission: Mission
var body: some View {
HStack {
Image(mission.image)
.resizable()
.scaledToFit()
.frame(width: 50, height: 50)
.padding()
VStack {
Text(mission.displayName)
.font(.headline)
.foregroundStyle(.white)
Text(mission.formattedLaunchDate)
.font(.caption)
.foregroundStyle(.white.opacity(0.7))
}
.padding(.vertical)
.frame(maxWidth: .infinity)
.background(.lightBackground)
}
.clipShape(.rect(cornerRadius: 10))
.overlay (
RoundedRectangle(cornerRadius: 10)
.stroke(.lightBackground)
)
}
}
#Preview {
MoonshootListRow(mission: Mission(id: 0, launchDate: .now, crew: [Mission.CrewRole(name: "test", role: "test")], description: "test"))
}