SwiftUI vertically misaligned text

爷,独闯天下 提交于 2019-12-13 17:42:40

问题


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:

Frame inspector:

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


回答1:


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.

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.




回答2:


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.




回答3:


I added alignment: .top to HStack. And now vertical alignment is fine.

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

    var body: some View {
        HStack(alignment: .top) {
            Button(action: { print("haha") }, label: {
                Text("NL")
                    .foregroundColor(Color.purple)
            })

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

To see why this happened you can add .border(Color.black) to all elements. As you can notice Text has different height.

Or use TextField instead of Text like below

        HStack {
            Button(action: { print("haha") }, label: {
                TextField("", text: .constant("NL"))
                    .fixedSize()
                    .foregroundColor(Color.purple)
            })

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

This issue is Text has not multiple size so SwiftUI can't align. You can also add .padding(.bottom, 1) to Text

        VStack {
            HStack {
                Button(action: { print("haha") }, label: {
                    Text("NL")
                        .foregroundColor(Color.purple)
                        .padding(.bottom, 1)
                })

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

More info

Check out my video.

VStack

If you use VStack to align multiple elements look at my explain here



来源:https://stackoverflow.com/questions/57612762/swiftui-vertically-misaligned-text

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!