7

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...

aheze
  • 24,434
  • 8
  • 68
  • 125
Mane Manero
  • 3,086
  • 5
  • 25
  • 47

2 Answers2

9

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")
    }
Kris McGinnes
  • 372
  • 2
  • 7
7

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

.buttonStyle(PlainButtonStyle())
zdravko zdravkin
  • 2,090
  • 19
  • 21
  • Thanks, iIt works, however the color of the button will be black instead of default blue. I changed the style to BorderlessButtonStyle, it now shows the default blue style. tested on iOS 13,14 with xcode 12. – xiang Oct 10 '21 at 13:14
  • 1
    This should actually be the accepted answer as you can still use "Button". – G. Marc Jan 20 '22 at 05:58