0

I have a simple SwiftUI row of buttons to mimic a keyboard layout. Just can't get the buttons to fill the height of the HStack. I can't tell where I need to give something height so it will look like a keyboard. No matter where I try to add height, the buttons still are small. macOS screenshot

struct KeyboardView: View {
  let rows = [String.keyboardFKeyRow, String.keyboardNumKeyRow, String.alpha1KeyRow, String.alpha2KeyRow, String.alpha3KeyRow, String.arrowKeyRow]
  var body: some View {
    VStack() {
      KeyRow(labels: String.keyboardFKeyRow).frame(height: 100)
      KeyRow(labels: String.keyboardNumKeyRow).frame(height: 100)
      KeyRow(labels: String.alpha1KeyRow).frame(height: 100)
      KeyRow(labels: String.alpha2KeyRow).frame(height: 100)
      KeyRow(labels: String.alpha3KeyRow).frame(height: 100)
      KeyRow(labels: String.arrowKeyRow).frame(height: 100)
    }
  }
}

struct KeyRow: View {
  var labels: [String]
  
  var body: some View {
    HStack() {
      Spacer()
      ForEach(labels, id: \.self) { label in
        Button {
          print("Key Clicked")
        } label: {
          Text(label.capitalized)
            .font(.body)
            .frame(minWidth: 60, maxWidth: 80, minHeight: 80, maxHeight: .infinity)
        }
      }
      Spacer()
    }
  }
}
2
  • Does this answer your question? In SwiftUI, How do I increase the height of a button? Commented Sep 15, 2022 at 22:40
  • Rob's answer here is far more helpful than anything else I've seen on Stack Overflow, and countless other sites, for that matter. Commented Sep 15, 2022 at 23:43

1 Answer 1

2

The .bordered button style on macOS has a hard-coded size and refuses to stretch vertically. If you need a different button height, either use the .borderless style or create your own ButtonStyle or PrimitiveButtonStyle, and (either way) draw the background yourself. For example, I got this result:

A row of three buttons. The first two buttons are both slightly bigger than their text labels. The third button has expanded to fill the container vertically.

from this playground:

import PlaygroundSupport
import SwiftUI

PlaygroundPage.current.setLiveView(HStack {

    // Default button style, Text label.
    Button("a", action: {})
        .background { Rectangle().stroke(.mint.opacity(0.5), lineWidth: 1).clipped() }
        .frame(maxHeight: .infinity)

    // Default button style, vertically greedy Text label.
    Button(action: {}, label: {
        Text("b")
            .frame(maxHeight: .infinity)
    })
    .background { Rectangle().stroke(.mint.opacity(0.5), lineWidth: 1).clipped() }
    .frame(maxHeight: .infinity)

    Button(action: {}, label: {
        Text("c")
            .fixedSize()
            .padding()
            .frame(maxHeight: .infinity)
            .background {
                RoundedRectangle(cornerRadius: 10)
                    .fill(Color(nsColor: .controlColor))
            }
    }).buttonStyle(.borderless)
        .background { Rectangle().stroke(.mint.opacity(0.5), lineWidth: 1).clipped() }
        .frame(maxHeight: .infinity)

}
    .background { Rectangle().stroke(.red.opacity(0.5), lineWidth: 1).clipped() }
    .frame(height: 100)
)
Sign up to request clarification or add additional context in comments.

1 Comment

The solution with borderless works well.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.