I have a difficult time to find a workaround to align multiline TextField
with another Text
in HStack
. I want to align it firstTextBaseline
. The problem is, TextField
jumps down when its text becomes empty and only the placeholder is shown.
I use these HStack
in the List
rows, but the alignment does not work even in the stripped and simplified code like this:
struct TextFieldAlignmentProblem: View {
@State private var text: String = ""
var body: some View {
HStack(alignment: .firstTextBaseline) {
Text("1")
TextField("Text", text: $text, axis: .vertical)
}
.padding()
}
}
If I remove axis: .vertical
or use .center
alignment instead of .firstTextBaseline
, the jumping problem disappears, but that is not the layout I need.
The problem looks quite simple, but I failed to find a suiting solution for now.
Unfortunately, it's a bug that happens on the axis: .vertical
when the field is empty.
You can make a placeholder to hold the textfield in the correct position:
struct TextFieldAlignmentProblem: View {
@State private var text: String = ""
private var placeholder: String { text.isEmpty ? " " : text } // 👈 Generate a correct placeholder. I have used a single space.
var body: some View {
HStack(alignment: .firstTextBaseline) {
Text("1")
TextField("Text", text: .constant(placeholder), axis: .vertical) // 👈 Use the placeholder as the base
.opacity(0) // 👈 Make it hidden keeping the frame
.overlay { // 👈 Put the actual TextField on top of the placeholder view
TextField("Text", text: $text, axis: .vertical)
}
}
.padding()
}
}
If you are not going to use different fonts, typefaces, dynamic types, etc, a very simple and quick workaround could be checking the condition and passing the (visually) correct alignment:
HStack(
alignment: text.isEmpty ? .center : .firstTextBaseline // 👈 Conditional alignment
) { ,,, }