调整窗口大小时,SwiftUI TextField 文本边界无法使用 GeometryReader 更新,导致外观错误

Posted

技术标签:

【中文标题】调整窗口大小时,SwiftUI TextField 文本边界无法使用 GeometryReader 更新,导致外观错误【英文标题】:SwiftUI TextField text bounds fail to update with GeometryReader when window resized, causing buggy looks 【发布时间】:2020-01-21 15:53:26 【问题描述】:

not-ios

错误的外观包括文本看起来被垂直截断,并且蓝色选择边框不匹配。这些问题直接相关,并在问题中进一步涉及。

有人告诉我,当我遇到 TextField 问题时,我应该提出个别问题。所以这里有一个。问题是当文本大小取决于窗口宽度时,调整窗口大小会给它一个错误的外观。看看截图。代码在VStackGeometryReader 中。

代码:

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))
    )

以下是显示此行为的屏幕截图。

普通窗口:

当我调整它的大小时它看起来像这样:

但是当我点击字段时,它又看起来正常了:

我还注意到蓝色选择边框没有缩放。我认为蓝色边框显示了文本的边框,所以这似乎与文本的截断直接相关。

我将如何解决这个问题?

一种可能的方法是在每次调整窗口大小时更新窗口,但出于性能原因我不愿意这样做。但如果性能不是这里的问题,我需要知道在视图中调整窗口大小时如何调用函数。

为了说明这一点,我不是在创建 iOS 应用程序,而是在创建 macOS 应用程序。

我的预期结果是当窗口调整大小时,我希望文本字段立即看起来像第三张图像,如果文本字段与新大小匹配,则文本边界匹配新大小,因此,蓝色边框将匹配文本字段,并且文本不会被截断。我可以以最有效的方式在我的代码中添加什么来修复它?如何使用 GeometryReader 更新文本字段边界?

注意:如果文本是在 TextField 中键入的,则不会发生此错误。仅当它为空时。

笔记总结:

我创建了一个 TextField TextField 的字体大小取决于 几何阅读器。 如果为空,则 TextField 的文本会显示为截断,直到被选中 如果在 文本字段 蓝色边框也与文本字段不匹配,因为我猜这代表了文本字段的边界,所以这与截断的文本直接相关。 您可能已经注意到新图像有一个更多世界选项按钮。忽略它。

鉴于此信息,如何使文本字段在调整大小时立即看起来像第三张图片,而不是第二张/第四张,所以我解决了这个问题?

有没有办法修复这个错误同时保留文本字段的外观?

【问题讨论】:

【参考方案1】:

根据我的调查,观察到的问题源于PlainTextFieldStyle 样式使用...没有解决方法(您可以向 Apple 报告反馈,因为这肯定是问题)。因此,如果主题问题很关键,我建议将SquareBorderTextFieldStyle 明确用于具有此类行为的文本字段(至少是暂时的),如下所示。 Square 样式在 Xcode 11.2 / macOS 10.15 发布的场景中经过测试和工作。

这是不同配置的结果:

截图结果代码如下:

        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))
                    )
            
        

【讨论】:

如何将其设为允许垂直调整大小的 RoundedBorderTextFieldStyle? 没办法。我测试了RoundedBorderTextFieldStyle,如果它可以工作,你知道... 好的,我再测试一下,然后接受你的回答 是否有其他方法,可以让 Square 样式不可见并保持圆角矩形背景? 或者有没有办法让圆角样式垂直伸缩?

以上是关于调整窗口大小时,SwiftUI TextField 文本边界无法使用 GeometryReader 更新,导致外观错误的主要内容,如果未能解决你的问题,请参考以下文章

SwiftUI:在输入之前将 TextField 大小扩展到字体大小

AppKit 上的 SwiftUI - 在弹出窗口中将焦点设置为 TextField

是否可以在 SwiftUI 中为 TextField 添加字距调整?

SwiftUI TextField Representable 不增加字体大小

调整大小时的 SwiftUI 文本剪辑

使用 SwiftUI 时无法正确调整 SKScene 的大小