I have a workout application using SwiftData where the user can start a new workout. When clicking the start button, the user is redirected to a new view (CurrentWorkoutView) in which a workout object is instantiated. The user could then save or cancel the workout.
I'm facing 2 problems:
This is a simplified version of the code:
// HomeView.swift
...
NavigationLink("Start Workout") {
CurrentWorkoutView()
}
...
// CurrentWorkoutView.swift
@Environment(\.dismiss) var dismiss
@Environment(\.modelContext) var context
@Bindable var workout: Workout = Workout()
var body: some View {
...
.toolbar {
ToolbarItem(placement: .confirmationAction) {
Button("Save") {
workout.end = Date.now
context.insert(workout)
dismiss()
}
}
ToolbarItem(placement: .cancellationAction) {
Button("Cancel") {
context.delete(workout)
try! context.save()
dismiss()
}
}
}
}
I've tried to set workout as nullable but, because it's bindable, I can't. It has to be bindable to allow for title, description, etc editing.
You should not use @Bindable when it’s the view that owns the object, use State instead here. And with @State we can make the property optional as well
@State private var workout: Workout?
Create it in onAppear
.onAppear {
workout = Workout()
}
And since the object has not been inserted into the ModelContext you don’t need to delete it either, just set it to nil in the Cancel button action