简体   繁体   中英

SwiftUI TextField text bounds fail to update with GeometryReader when window resized, causing buggy looks

The buggy looks include the text looks vertically truncated, and the blue selection border doesn't match. These issues are directly related and is touched upon further in the question.

I have been told that I should ask individual questions when I am experiencing TextField issues. So here is one. The issue is when the text size is dependant on window width, resizing the window gives it a buggy look. Take a look at the screenshots. The code is in a VStack and GeometryReader .

Code:

TextField("World Name", text: self.$WorldName)
    .font(.system(size: geometry.size.width/24))
    .textFieldStyle(PlainTextFieldStyle())
    .padding([.leading, .trailing], 6)
    .frame(width: geometry.size.width*0.75, height: geometry.size.width/20)
    .background(
        RoundedRectangle(cornerRadius: 8)
            .fill(Color.init(white: 0.28))
    )
TextField("World Seed", text: self.$WorldSeed)
    .font(.system(size: geometry.size.width/24))
    .textFieldStyle(PlainTextFieldStyle())
    .padding([.leading, .trailing], 6)
    .frame(width: geometry.size.width*0.75, height: geometry.size.width/20)
    .background(
        RoundedRectangle(cornerRadius: 8)
            .fill(Color.init(white: 0.28))
    )

Here are screenshots showing this behavior.

Normal Window:

在此处输入图片说明

It looks like this when I resize it:

在此处输入图片说明

But as soon as I click on the fields, it looks normal again:

在此处输入图片说明

I have also noticed that the blue selection border does not scale. I presume that the blue border shows the border of the text, so this seems directly tied to the truncation of the text.

在此处输入图片说明

How would I go about fixing this issue?

A possible approach would be updating the window every time it is resized, but I am reluctant to do that for performance reasons. But if performance is not an issue here, I need to know how to call a function when the window is resized from within the view.

And to make this redundantly clear, I am not creating iOS apps, I am creating macOS apps.

My expected result is for when the window resizes, I want the textfield to immediately look like the third image, where the text bounds match the new size if the textfield, and thus, the blue border will match the textfield, and the text will not appear truncated. What can I add to my code to fix it, in the most efficient way possible? How can I update the textfield bounds with the GeometryReader?

Note: This bug does not happen IF text is TYPED in the TextField. ONLY when it is empty.

Summarised list of notes:

  • I have created a TextField
  • TextField's Font size is dependant on the GeometryReader.
  • If empty, the TextField's text appears truncated until selected
  • The bug does not occur if there is text typed in the textfield
  • The blue border also does not match the textfield, and since I guess this represents the bounds of the textfield, this is directly related to the truncated text.
  • You might have noticed that the new image has a more world options button. Ignore it.

Given this information, how can I make the textfields immediately look like the third image when resizing, rather than the second/fourth, so I fix this issue?

Is there any way to fix this bug while preserving the look of the text fields?

By my investigation the observed issue is originated from PlainTextFieldStyle style usage... no workaround for this (you can report feedback to Apple cause it is definitely issue). So if the topic issue is critical I recommend to use SquareBorderTextFieldStyle explicitly as below for text fields with such behaviour (at least temporary). Square style tested & worked in the posted scenario with Xcode 11.2 / macOS 10.15.

Here is result of different configurations:

在此处输入图片说明

Here is code for screenshot result:

        GeometryReader { geometry in
            VStack {
                TextField("World Name", text: self.$WorldName)
                    .font(.system(size: geometry.size.width/24))
                    .textFieldStyle(SquareBorderTextFieldStyle())
                    .padding([.leading, .trailing], 6)
                    .frame(width: geometry.size.width*0.75, height: geometry.size.width/20)
//                    .background(
//                        RoundedRectangle(cornerRadius: 8)
//                            .fill(Color.init(white: 0.28))
//                    )
                TextField("World Seed", text: self.$WorldSeed)
                    .font(.system(size: geometry.size.width/24))
                    .textFieldStyle(PlainTextFieldStyle())
                    .padding([.leading, .trailing], 6)
                    .frame(width: geometry.size.width*0.75, height: geometry.size.width/20)
                    .background(
                        RoundedRectangle(cornerRadius: 8)
                            .fill(Color.init(white: 0.28))
                    )
            }
        }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM