I am trying to build a ContextMenu
to allow the app user to Edit or Remove existing workouts from its collection when long pressing one of the workouts, but somehow to Workout selection is not consistent between Edit and Remove actions.
let workouts = workoutManager.getAllWorkoutsFromCollection()
if workouts.count > 0 {
ForEach(workouts) { workout in
WorkoutCardView(workout: workout)
.contextMenu {
Button {
print("Edit Workout: \(workout.title)") // for debug purpose
showEditWorkoutSheet.toggle()
} label: {
Label("Edit Workout", systemImage: "square.and.pencil")
}
Button(role: .destructive) {
print("Delete Workout: \(workout.title)") // for debug purpose
workoutManager.removeWorkoutFromCollection(workout)
} label: {
Label("Delete Workout", systemImage: "trash")
}
}
.sheet(isPresented: $showEditWorkoutSheet) {
AWSheetView(workout: workout, editWorkout: true)
}
}
}
workoutManager.getAllWorkoutsFromCollection()
returns all workouts as an array of Workout custom data type.
func removeWorkoutFromCollection(_ workout: Workout) {
print("WorkoutManager::removeWorkoutFromCollection: \(workout.title)") // for debug purpose
workouts.removeAll(where: { $0.id == workout.id } )
}
func updateWorkout(_ workout: Workout) {
if let index = workouts.firstIndex(where: { $0.id == workout.id } ) {
print("WorkoutManager::updateWorkout: \(workout.title)") // for debug purpose
workouts[index] = workout
}
}
Inside AWSheetView
I have the followings:
@State var workout: Workout = Workout()
var editWorkout: Bool = false
I am also building an empty Workout
here because I am using AWSheetView to add a new Workout
to the collection but also to edit an existing workout based on editWorkout
variable.
When long pressing to a Workout and selecting Delete, the selected workout gets deleted from collection and I have the following console output:
Delete Workout: Legs Day
WorkoutManager::removeWorkoutFromCollection: Legs Day
but when pressing Edit the output looks like below and somehow always the first workout is received in AWSheetView instead of the selected one:
Edit Workout: Legs Day
WorkoutManager::updateWorkout: Upper body
Does anyone knows what am I doing wrong here? I am trying for severals days to solve it but no results.
Below are 2 screenshots. In the second screenshot you can see how AWSheetView
looks like when pressing Edit on "Legs day" workout.
Legs day long press:
The result when pressing Edit on "Legs day" workout:
The solution pointed out by Asperi (check here the solution) works very well.
This is new implementation based on the above link:
@State private var selectedWorkout: Workout? = nil
let workouts = workoutManager.getAllWorkoutsFromCollection()
if workouts.count > 0 {
ForEach(workouts) { workout in
WorkoutCardView(workout: workout)
.contextMenu {
Button {
print("Edit Workout: \(workout.title)") // for debug purpose
selectedWorkout = workout
} label: {
Label("Edit Workout", systemImage: "square.and.pencil")
}
Button(role: .destructive) {
print("Delete Workout: \(workout.title)") // for debug purpose
workoutManager.removeWorkoutFromCollection(workout)
} label: {
Label("Delete Workout", systemImage: "trash")
}
}
}
.sheet(item: self.$selectedWorkout) { selectedWorkout in
AWSheetView(workout: selectedWorkout, editWorkout: true)
}
} else {
Text("No workouts found.")
.font(.system(size: 16))
.foregroundColor(.red)
}