Hi! I'm working on the Navigation challenge (day 46) and upgrading my Moonshot app to use NavigationLink(value:).
I successfully changed it in multiple places but I'm stuck on the one in the ContentView.
Here's the code I have for the ContentView:
//
// ContentView.swift
// Moonshot
//
// Created by Paul Newman on 11/7/23.
//
import SwiftUI
struct ContentView: View {
@State private var layout = "grid"
let layouts = ["grid", "list"]
let astronauts: [String: Astronaut] = Bundle.main.decode("astronauts.json")
let missions: [Mission] = Bundle.main.decode("missions.json")
var columns: [GridItem] {
switch layout {
case "grid":
return [GridItem(.adaptive(minimum: 150))]
case "list":
return [GridItem(.flexible())]
default:
return [GridItem(.adaptive(minimum: 150))]
}
}
var body: some View {
NavigationStack {
VStack {
ScrollView {
LazyVGrid(columns: columns) {
ForEach(missions, id: \.id) {mission in
NavigationLink(value: mission) {
MissionLabel(mission: mission, layout: layout)
}
}
}
.padding([.horizontal, .bottom])
}
.padding(.top, 16)
.navigationTitle("Moonshot")
.toolbar {
Picker("", selection: $layout) {
Image(systemName: "rectangle.grid.1x2.fill").tag("list")
Image(systemName: "square.grid.2x2.fill").tag("grid")
}
.pickerStyle(.segmented)
}
.background(.darkBackground)
.preferredColorScheme(.dark)
}
.navigationDestination(for: Mission.self) { mission in
MissionView(mission: mission, astronauts: astronauts)
// Text("\(mission.description)")
}
}
}
}
#Preview {
ContentView()
}
When I comment the MissionView inside the .navigationDestination and use the TextView instead (for the testing purposes), it works just fine. But when I try to use MissionView as a destination, I get the following message in the console:
A NavigationLink is presenting a value of type “Mission” but there is no matching navigationDestination declaration visible from the location of the link. The link cannot be activated.
Here's the MissionView code:
//
// MissionView.swift
// Moonshot
//
// Created by Paul Newman on 11/14/23.
//
import SwiftUI
struct MissionView: View, Hashable {
struct crewMember: Hashable {
var role: String
var astronaut: Astronaut
}
let mission: Mission
let crew: [crewMember]
let astronauts: [String: Astronaut]
var body: some View {
NavigationStack {
ScrollView {
VStack(spacing: 40) {
Image(mission.image)
.resizable()
.scaledToFit()
.containerRelativeFrame(.horizontal) { width, axis in
width * 0.5
}
.padding(.top, 8)
VStack(alignment: .leading, spacing: 16) {
Text("Mission highlights")
.font(.title.bold())
Text(mission.description)
.padding(.bottom)
DividerCustom()
}
.padding(.horizontal)
}
CrewView(mission: mission, astronauts: astronauts)
}
}
.navigationTitle(mission.displayName)
.navigationBarTitleDisplayMode(.inline)
.background(.darkBackground)
}
init(mission: Mission, astronauts: [String: Astronaut]) {
self.mission = mission
self.astronauts = astronauts
self.crew = mission.crew.map { member in
if let astronaut = astronauts[member.name] {
return crewMember(role: member.role, astronaut: astronaut)
} else {
fatalError("Missing \(member.name)")
}
}
}
}
#Preview {
let missions: [Mission] = Bundle.main.decode("missions.json")
let astronauts: [String: Astronaut] = Bundle.main.decode("astronauts.json")
return MissionView(mission: missions[0], astronauts: astronauts)
.preferredColorScheme(.dark)
}
Any suggestions on how to fix the issue are appreciated ❤️