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.
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()
}
}
}
CodePudding user response:
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:
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)
)