In my app, I have:
.navigationDestination(item: self.$selectedProject) { selectedProject in
ProjectView(project: Binding<Project>(
get: { selectedProject },
set: { self.selectedProject = $0 }
))
}
Where selectedProject
is a property in my view declared as @State private var selectedProject: Project?
(Project
is a model object).
I'm simply wanting to unwrap self.selectedProject
into a Binding<Project>
and send it as a parameter to ProjectView
.
The above solution is the best I've come up with so far, but passing the closure parameter selectedProject
for the get:
is bugging me because it only captures a local copy. I also don't want to use self.selectedProject!
for the get:
as I try to avoid force unwrapping.
I've also tried doing it the conventional way:
.navigationDestination(item: self.$selectedProject) { _ in
if let selectedProject = Binding(self.$selectedProject) {
ProjectView(project: selectedProject)
}
else {
Helpers.errorText()
}
}
Weirdly though, it's crashing with an
EXC_BREAKPOINT
when I hit the back button on ProjectView
to return to this current view that has the .navigationDestination
code.
I'm just wondering what the safest and best way is to do this.
You could try a different approach using .navigationDestination(isPresented: $showProjectView)
,
as shown in this example code:
struct Project: Identifiable, Hashable {
let id = UUID()
var name: String
}
struct ContentView: View {
@State private var selectedProject: Project?
@State private var showProjectView = false
var body: some View {
Text("selected project: \(selectedProject?.name ?? "none")")
.padding(30)
.border(.green)
NavigationStack {
Button("testing") {
if selectedProject == nil {
selectedProject = Project(name: "Mickey Mouse")
}
showProjectView = true
}
.navigationDestination(isPresented: $showProjectView) {
if let binding = Binding($selectedProject) {
ProjectView(project: binding)
} else {
Text("No project selected")
}
}
}
}
}
struct ProjectView: View {
@Binding var project: Project
var body: some View {
TextField("Project name", text: $project.name).border(.red)
}
}