I want to show a Form with a HStack in it. In this HStack I have a Text and a TextField. The TextField should align on the right side, the text on the left. I've tried it with Spacers, with the TextBaseline, with Grids but nothing worked.
struct GeschenkeDetailView: View {
@State private var anzahlItems: Int = 0
@State private var showArrivedAlert: Bool = false
@State private var showDeleteAlert: Bool = false
@Binding var personName: String
@Binding var items: [GeschenkItem]
var body: some View {
Form {
Section("Für wen ist das Geschenk?") {
TextField("Name", text: $personName)
.bold()
}
ForEach(items.indices, id: \.self) { index in
let item = items[index]
Section("Produkt \(anzahlItems + index + 1)") {
HStack {
Text("Produkt:")
Spacer()
//Text(item.name)
TextField("Produktname", text: $items[index].name)
.aspectRatio(contentMode: .fit)
}
Picker("Status:", selection: $items[index].status) {
ForEach(Status.allCases, id: \.self) { status in
Text(status.asString).tag(status)
}
}
.pickerStyle(.menu)
.accentColor(item.status.color)
HStack {
Text("Preis:")
Spacer()
Text("\(item.preis)€")
}
LazyVGrid(columns: [GridItem(), GridItem()]) {
Button(action: {
showArrivedAlert = true
}, label: {
Text("Produkt angekommen")
.multilineTextAlignment(.center)
.foregroundStyle(.green)
})
.buttonStyle(BorderlessButtonStyle())
Button(action: {
showDeleteAlert = true
}, label: {
Text("Produkt löschen")
.multilineTextAlignment(.center)
.foregroundStyle(.red)
})
.buttonStyle(BorderlessButtonStyle())
}
}
}
Section {
Button(action: {}, label: {
Text("Angekommene Produkte")
})
}
.frame(maxWidth: .infinity)
Section {
Button("Person löschen", role: .destructive) {
}
}
.frame(maxWidth: .infinity)
}
.alert("Produkt angekommen?", isPresented: $showArrivedAlert) {
Button("Abbrechen") {
}
Button(action: {}, label: {
Text("Angekommen")
.bold()
})
} message: {
Text("Sie können diese Produkte jederzeit erneut einsehen und wiederherstellen.")
}
.alert("Produkt löschen?", isPresented: $showDeleteAlert) {
Button("Behalten", role: .cancel) {
}
Button("Löschen", role: .destructive) {
}
} message: {
Text("Bist du dir sicher das du dieses Produkt löschen möchtest?")
}
}
}
I made it with a fixed size of the Textfield, but then the textfield was to small. It was about 50 frame. I want the textfield to align on the right side and when the user is typing something it should expand to the left side. It is about the "Produkt:" component.
The alignment of the text inside the TextField
can be controlled by applying .multilineTextAlignment
.
You want the alignment to be .leading
when the field has focus, but .trailing
at other times. This means, you need to detect when the field has focus. A FocusState
variable can be used for this.
@FocusState private var focusedField: Int?
Then you just need to change the HStack
that contains the field to the following:
HStack {
Text("Produkt:")
TextField("Produktname", text: $items[index].name)
.focused($focusedField, equals: index)
.multilineTextAlignment(focusedField == index ? .leading : .trailing)
}