SwiftUI is pressing both buttons in a List

I have a List which acts like a form where you can enter values. It uses a custom View struct SectionArea to separate the various sections and cut down on code duplication, like this:

List {
  SectionArea(title: "Section One", height: 176, horizontalPadding: 0, roundCorners: (0, 0, 0, 0)) {
    VStack {
      Button {
        print("Pressed Button One")
        fullScreenViewChoice = .optionOne
        showSubView.toggle()
      } label: {
        HStack {
          Text("Button One")
          Spacer()
          Image(systemName: "chevron.right")
        }
      }
      .frame(height: 40)
      Divider()
  
      Button {
        print("Pressed Button Two")
        fullScreenViewChoice = .optionTwo
        showSubView.toggle()
      } label: {
        HStack {
          Text("Button Two")
          Spacer()
          Image(systemName: "chevron.right")
        }
      }
      .frame(height: 40)
      Divider()
    }
  }
}
.listStyle(.plain)
.listRowSpacing(0)

It works fine, but regardless of which button I press it always acts as though both buttons have been pressed. Say I press Button One, the console will display:

Pressed Button One
Pressed Button Two

Can someone tell me where I'm going wrong here, please? Thanks!

EDIT: Actually, it doesn't look like it's because of the SectionArea struct, because I've taken the code from there and wrapped it around the content directly, rather than using that struct, and it still does it.

I've removed everything and just put this:

List {
  VStack {
    ButtonOne
    ButtonTwo
  }
}

It still presses both buttons.

Accepted Reply

Well, I've had a look around, and it seems that the fix is to add .buttonStyle(BorderlessButtonStyle()) to the buttons (or the List as a whole).

Why changing the button style would fix this, is beyond me. Just another wacky thing about SwiftUI, I guess.

Replies

Well, I've had a look around, and it seems that the fix is to add .buttonStyle(BorderlessButtonStyle()) to the buttons (or the List as a whole).

Why changing the button style would fix this, is beyond me. Just another wacky thing about SwiftUI, I guess.

I reproduced the behaviour you described.

Apparently, that's a long lasting issue: https://developer.apple.com/forums/thread/651572

More insight here, even though does not explain fully the cause: https://stackoverflow.com/questions/70399810/buttons-in-swiftui-list-foreach-view-trigger-even-when-not-tapped

It also seems VStack is causing a problem, just as if the tap in button was passed to VStack and then to all…. The same occurs when you tap in VStack outside of buttons.

I simplified to show:

struct ContentView: View {
    
    var body: some View {
        List {
//            SectionArea(title: "Section One", height: 176, horizontalPadding: 0, roundCorners: (0, 0, 0, 0)) {
//                VStack {
                    Button {
                        print("Pressed Button One")
//                        fullScreenViewChoice = .optionOne
//                        showSubView.toggle()
                    } label: {
                        HStack {
                            Text("Button One")
                            Spacer()
                            Image(systemName: "chevron.right")
                        }
                    }
                    .frame(height: 40)
                    .background(.red)
//                    Divider()
                    
                    Button {
                        print("Pressed Button Two")
//                        fullScreenViewChoice = .optionTwo
//                        showSubView.toggle()
                    } label: {
                        HStack {
                            Text("Button Two")
                            Spacer()
                            Image(systemName: "chevron.right")
                        }
                    }
                    .frame(height: 40)
                    .background(.blue)
//                    Divider()
//                }
//            }
        }
        .listStyle(.plain)
        .listRowSpacing(0)
    }
}

Sometimes, working with SwiftUI is like painting with boxing gloves…

  • it really is infuriating sometimes. For example, the new ColorPicker. It's a View so it has to be displayed as a View, and it adds its own little palette picker so you can't just say, "Show a ColorPicker when the user presses this other Text button I've created". You always see the palette button, so if you want to have a few of them on different part s of your app, you get that stupid palette everywhere. I just want to show a ColorPicker when the user taps some other button of my design.

Add a Comment