Home > front end >  Buttons in SwiftUI List ForEach view trigger even when not "tapped"?
Buttons in SwiftUI List ForEach view trigger even when not "tapped"?

Time:12-18

I have the following code:

struct ButtonTapTest: View {
    
    let items = [1, 2, 3]
    
    var body: some View {
        
        List {
            ForEach(items, id:\.self) { item in
                CellTestView()
            }
        }
        
    }
}


struct CellTestView:View {
    
    
    var body: some View {
        
        VStack {
            
            Button {
                print("TOP")
            } label: {
                Image(systemName: "play.fill")
                    .font(.system(size: 40))
                    .foregroundColor(.red)
            }
            .border(.red)
            
            Spacer()
            
            Button {
                print("BOTTOM")
                
            } label: {
                Image(systemName: "play")
                    .font(.system(size: 40))
                    .foregroundColor(.red)
            }
            .border(.yellow)
            
        }
        
    }
    
}

Creates the following screen:

enter image description here

Problem:

Both button actions get triggered in the cell regardless of where I tap on the CellTestView. I want the individual button actions to trigger separately, each only when its button gets tapped, and not when I tap outside anywhere else on the cell.

You can see in the gif below that it does not matter where I tap on the CellTestView, both button actions get trigger regardless where on the view I tap, and both "TOP" and "BOTTOM" logs trigger at the same time.

How can I fix this so the two buttons in the cell receive the tap independently and only when the tap is inside the related button?

enter image description here

CodePudding user response:

My workaround for this problem is to wrap each button in its own VStack or HStack.

CodePudding user response:

when you have a list, tapping on a list row will trigger both buttons. Try this code to make each "button" equivalent, trigger separately.

struct CellTestView: View {

    var body: some View {
        VStack {
            Image(systemName: "play.fill") .font(.system(size: 40)).foregroundColor(.red).border(.red)
                .onTapGesture {
                    print("-----> playFill \(playFill)")
                }
            Spacer()
            Image(systemName: "play") .font(.system(size: 40)).foregroundColor(.red).border(.yellow)
                .onTapGesture {
                    print("--> play \(play)")
                }
        }
    }
}

CodePudding user response:

Whenever you have multiple buttons in a list row, you need to manually set the button style to .borderless or .plain.

CellTestView()
    .buttonStyle(.borderless)

Result:

Tapping top and bottom button results in separate print statements

  • Related