SwiftUI - cells (inside Form) with clickable buttons

Viewed 3190

Goals:

  1. Create a row/cell with buttons
  2. Embed row/cell in a Form

What I did:

  1. I created a cell, with buttons.
struct PointTypeButtons : View {
    var body: some View {
        
        VStack {
            HStack {
                Text("Aligment")
                    .font(.subheadline)
                Spacer()
            }
            
            HStack {
                
                Button(action: {}) {
                    Image(systemName: "text.alignleft")
                        .padding(.horizontal, 25.0)
                        .padding(.vertical)
                        .background(Color.black)
                        .cornerRadius(4)
                }
                Button(action: {}) {
                    Image(systemName: "text.aligncenter")
                        .padding(.horizontal, 25.0)
                        .padding(.vertical)
                        .background(Color.black)
                        .cornerRadius(4)
                }
                Button(action: {}) {
                    Image(systemName: "text.aligncenter")
                        .padding(.horizontal, 25.0)
                        .padding(.vertical)
                        .background(Color.black)
                        .cornerRadius(4)
                }
                Button(action: {}) {
                    Image(systemName: "text.alignright")
                        .padding(.horizontal, 25.0)
                        .padding(.vertical)
                        .background(Color.black)
                        .cornerRadius(4)
                }
            }
        }
        .frame(height: nil)
    }
}

4 buttons in horizontal row, with "Alignment" text above on left

  1. Then I placed this cell into a Form:
struct ToolbarBezier : View {
    var body: some View {
        HStack {
            Spacer()
            
            Form {
                PointTypeButtons()
            }
            .frame(width: 320.0)
            
        }
    }
}

The buttons and text embedded in Form

Problem: When I tap, I now select the whole cell, NOT the buttons.

Question: How can I tap and select the buttons? Should I expose all buttons (NOT the cell) on the form? Problem is that in this case the form will have a huge codebase, and I wanted to keep things clean and organized...

2 Answers

As of beta 5, SwiftUI will consider any View containing a Button as a "form button". This means the entire cell becomes the tappable target. In my experience, it seems to choose the last button if you have more than one.

To work around this, you can choose to not use a button at all. Instead, use onTapGesture() event to detect taps.

Here is your same image button, but transformed into a tappable image. The foreground color was coming from the button style, so you must define that explicitly now.

Image(systemName: "text.alignleft")
    .foregroundColor(Color.accentColor)
    .padding(.horizontal, 25.0)
    .padding(.vertical)
    .background(Color.black)
    .cornerRadius(4)
    .onTapGesture {
        print("align left tapped")
    }

Just add to your View (PointTypeButtons), and will recognize each button tap inside Form

.buttonStyle(PlainButtonStyle())
Related