Strange buttons behaviour in a list (SwiftUI)

Viewed 219

In the following SwiftUI code I noticed some unexpected behaviour.

I wonder if this is a bug, if this is normal or if I am only missing something obvious.

List {
    ForEach(self.myList, id: \.self.name) {
        item in
        HStack {
            Spacer()
            Button(action: {
                print("Button One tapped!")
                ....
            }) {
                item.name.map(Text.init)
                    .font(.largeTitle)
                    .foregroundColor(.secondary)
            }
            Spacer()
            Button(action: {
                print("Button Two tapped!")
                ....
            }) {
                Image(systemName: "pencil.circle")
                    .font(.title)
                    .foregroundColor(.secondary)
                    .padding(.leading, 17)
            }
        }
    }
    .onDelete(perform: deleteFunc)
}

Now here is what happens when tapping one of the two buttons on a row. I can see these two messages:

Button One tapped!
Button Two tapped!

I expect to see only one message, depending on the button tapped.

If the order of the messages varied according to the button tapped; I could use a boolean or two to enforce the end result I want. But the two messages always appear in the same order.

Has anyone had the same experience? Or does anyone see any mistake?

1 Answers

Use PlainButtonStyle (or any custom one), because default button style is detected by List automatically to highlight entire row.

Here is a simplified (from your code) demo:

struct DemoListWithButtons: View {
    var body: some View {
        List {
            ForEach(0..<5, id: \.self) {
                item in
                HStack {
                    Spacer()
                    Button(action: {
                        print("Button One tapped!")
                    }) {
                        Text("First")
                    }.buttonStyle(PlainButtonStyle()) // << here !!
                    Spacer()
                    Button(action: {
                        print("Button Two tapped!")
                    }) {
                        Text("Second")
                    }.buttonStyle(PlainButtonStyle()) // << here !!
                }
            }
        }
    }
}
Related