This is a follow up to my previous question: Aligning left side of TextFields
I am trying to use a Grid
to mimic the layout of controls as seen in Xcode:
I am almost there, this is my current result (just ignore the values in the Picker
):
How can I fix my code so that the TextField
and Stepper
in the HStack
look as in the Xcode example?
macOS 15.6.1, Xcode 16.4
Here is my code:
import SwiftUI
struct ContentView: View {
enum Setting: String, CaseIterable {
case one
case twp
case three
}
@State private var unit: Setting = .one
@State private var quantity1: Int = 4
@State private var quantity2: Int = 4
static let numberFormatter = NumberFormatter()
var body: some View {
ScrollView {
Grid(horizontalSpacing: 5, verticalSpacing: 5) {
GridRow {
Text("Text Encoding")
.font(.system(size: 11))
.gridColumnAlignment(.trailing)
Picker("", selection: $unit) {
ForEach(Setting.allCases, id: \.self) { unit in
Text(unit.rawValue)
}
}
.gridCellColumns(2)
.pickerStyle(.menu)
.controlSize(.small)
}
GridRow {
Text("Line Endings")
.font(.system(size: 11))
.gridColumnAlignment(.trailing)
Picker("", selection: $unit) {
ForEach(Setting.allCases, id: \.self) { unit in
Text(unit.rawValue)
}
}
.gridCellColumns(2)
.pickerStyle(.menu)
.controlSize(.small)
}
Divider()
GridRow {
Text("Indent Using")
.font(.system(size: 11))
.gridColumnAlignment(.trailing)
Picker("", selection: $unit) {
ForEach(Setting.allCases, id: \.self) { unit in
Text(unit.rawValue)
}
}
.gridCellColumns(2)
.pickerStyle(.menu)
.controlSize(.small)
}
GridRow {
Text("Widths")
.font(.system(size: 11))
.gridColumnAlignment(.trailing)
HStack {
TextField("", value: $quantity1, formatter: numberFormatter)
Stepper("", value: $quantity1)
}
.controlSize(.small)
.font(.system(size: 11))
HStack {
TextField("", value: $quantity2, formatter: numberFormatter)
Stepper("", value: $quantity2)
}
.controlSize(.small)
.font(.system(size: 11))
}
Divider()
}
.padding()
}
}
}
The reason why there is more gap between the labels and the controls in the first three rows is because the empty labels are occupying some space. This can be avoided by applying .labelsHidden()
to each Picker
. But since the Stepper
have no labels either, you can just apply it to the whole Grid
instead:
Grid(horizontalSpacing: 5, verticalSpacing: 5) {
// ...
}
.labelsHidden() // 👈 here
.padding()