'SwiftUI Picker and Buttons inside same Form section are triggered by the same user click

I have this AddWorkoutView and I am trying to build some forms similar to what Apple did with "Add new contact" sheet form. Right now I am trying to add a form more complex than a simple TextField (something similar to "add address" from Apple contacts but I am facing the following issues:

  • in the Exercises section when pressing on a new created entry (exercise), both Picker and delete Button are triggered at the same time and the Picker gets automatically closed as soon as it gets open and the selected entry is also deleted when going back to AddWorkoutView.

Does anyone have any idea on how Apple implemented this kind of complex form like in the screenshow below?

Thanks to RogerTheShrubber response here I managed to somehow implement at least the add button and to dynamically display all the content I previously added, but I don't know to bring together multiple TextFields/Pickers/any other stuff in the same form.

Check here about what kind of form I am talking about

struct AddWorkoutView: View {
    @EnvironmentObject var workoutManager: WorkoutManager
    @EnvironmentObject var dateModel: DateModel
    
    @Environment(\.presentationMode) var presentationMode
    
    @State var workout: Workout = Workout()
    @State var exercises: [Exercise] = [Exercise]()
    
    func getBinding(forIndex index: Int) -> Binding<Exercise> {
        return Binding<Exercise>(get: { workout.exercises[index]      },
                                 set: { workout.exercises[index] = $0 })
    }
    
    var body: some View {
        NavigationView {
            Form {
                Section("Workout") {
                    TextField("Title", text: $workout.title)
                    TextField("Description", text: $workout.description)
                }
                
                Section("Exercises") {
                    ForEach(0..<workout.exercises.count, id: \.self) { index in
                        HStack {
                            Button(action: { workout.exercises.remove(at: index) }) {
                                Image(systemName: "minus.circle.fill")
                                    .foregroundColor(.red)
                                    .padding(.horizontal)
                            }
                            Divider()
                            VStack {
                                TextField("Title", text: $workout.exercises[index].title)
                                Divider()
                                Picker(selection: getBinding(forIndex: index).type, label: Text("Type")) {
                                    ForEach(ExerciseType.allCases, id: \.self) { value in
                                        Text(value.rawValue)
                                            .tag(value)
                                    }
                                }
                            }
                        }
                    }
                    Button {
                        workout.exercises.append(Exercise())
                    } label: {
                        HStack(spacing: 0) {
                            Image(systemName: "plus.circle.fill")
                                .foregroundColor(.green)
                                .padding(.trailing)
                            Text("add exercise")
                        }
                    }
                }
            }
            .navigationTitle("Create new Workout")
            .navigationBarTitleDisplayMode(.inline)
            .toolbar {
                ToolbarItem(placement: .cancellationAction) {
                    Button {
                        presentationMode.wrappedValue.dismiss()
                    } label: {
                        Text("Cancel")
                    }
                    .accessibilityLabel("Cancel adding Workout")
                }
                ToolbarItem(placement: .confirmationAction) {
                    Button {
                        
                    } label: {
                        Text("Done")
                    }
                    .accessibilityLabel("Confirm adding the new Workout")
                }
            }
        }
    }
}


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source