Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SwiftUI vertically misaligned text

I have some vertically misaligned text and I don't know why...

The code:

struct IBANInputView: View {
    @State var securityDigits = ""
    @State var bankCode = ""
    @State var accountNumber = ""

    var body: some View {
        HStack {
            Button(action: onCountryButtonTapped, label: {
                Text("NL")
                    .foregroundColor(Color.purple)
            })
            TextField("00", text: $securityDigits)
                .fixedSize()
            TextField("BANK", text: $bankCode)
                .fixedSize()
            TextField("0000 0000 00", text: $accountNumber)
        }
    }

    func onCountryButtonTapped() {
        print("LOL")
    }
}

Preview: Misaligned text

Frame inspector: enter image description here

How come the text is vertically misaligned and how can I fix it?

like image 504
ErikBrandsma Avatar asked Sep 17 '26 17:09

ErikBrandsma


2 Answers

This is happening because by default your HStack's vertical alignment is .center. I was able to achieve what you wanted by setting the HStack's vertical alignment to .firstTextBaseline and then adjusting the button's vertical alignment slightly.

    HStack(alignment: .firstTextBaseline) {
        Button(action: { print("haha") }, label: {
            Text("NL")
                .foregroundColor(Color.purple)
        })
            .alignmentGuide(.firstTextBaseline, computeValue: { return $0[.bottom] + 1.5 })

        TextField("00", text: $securityDigits)
            .fixedSize()
        TextField("BANK", text: $bankCode)
            .fixedSize()
        TextField("0000 0000 00", text: $accountNumber)
    }

Here I'm saying the first text baseline of the button is the button's .bottom and then moving that baseline up ever so slightly. You may have to experiment with values but I found this to be the most visually correct for your use-case.

enter image description here

It seems to me there's a bug in Button though by virtue of it not properly advertising the first text baseline in the button itself. This could potentially be cleaner by making a .firstTextBaseline-aware Button "subclass" that you can reuse elsewhere instead of making micro-adjustments everywhere.

like image 179
Procrastin8 Avatar answered Sep 19 '26 12:09

Procrastin8


Vertical misalignment

The Text inside the button does that. Try to use a constant text field.

Button(action: onCountryButtonTapped, label: {
    TextField("NL", text: .constant("NL"))
    .fixedSize()
    .disabled(true)
    .foregroundColor(Color.purple)
})

Size difference

The placeholder values of TextField have a different size. Once you enter text it should look the same.

like image 45
Fabian Avatar answered Sep 19 '26 11:09

Fabian



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!