forrest
forrest

Reputation: 10972

How do I keep multiple button actions separate in SwiftUI ForEach content?

I have a list of items with a checkbox a title and a timer icon:

enter image description here

The checkbox is a button and the timer icon is a button that have unique actions associated with them. However, if I tap anywhere inside the cell, it triggers both button actions simultaneously. It is intended that they operate independently of each other as well as the tap in the cell. How do I modify the following code to keep the actions separate?

List {
      ForEach(tasks, id: \.self) { task in
            HStack {

                Button(action: {
                    task.isComplete.toggle()
                    try? self.moc.save()
                    print("Done button tapped")
                }) {
                    Image(systemName: task.isComplete ? "square.fill" : "square")
                }
                .padding()

                Text(task.name ?? "Unknown Task")
                Spacer()

                Button(action: {
                    print("timer button tapped")
                }) {
                    Image("timer")
                }    
            }
        }
        .onDelete(perform: deleteTask)
    }

Upvotes: 1

Views: 2250

Answers (1)

Asperi
Asperi

Reputation: 257493

This is default behaviour of List, it identifies Button in row and makes entire row active, use instead .onTapGesture as below

List {
      ForEach(tasks, id: \.self) { task in
            HStack {

                Image(systemName: task.isComplete ? "square.fill" : "square")
                .padding()
                .onTapGesture {
                    task.isComplete.toggle()
                    try? self.moc.save()
                    print("Done button tapped")
                }

                Text(task.name ?? "Unknown Task")
                Spacer()

                Image("timer")
                .onTapGesture {
                    print("timer button tapped")
                }    
            }
        }
        .onDelete(perform: deleteTask)
    }

Upvotes: 10

Related Questions