SwiftUI TextField 绑定到 Double 不使用自定义格式化程序

Posted

技术标签:

【中文标题】SwiftUI TextField 绑定到 Double 不使用自定义格式化程序【英文标题】:SwiftUI TextField binding to Double not working with custom Formatter 【发布时间】:2019-07-09 18:50:46 【问题描述】:

我有一个绑定到由 SwiftUI TextField 设置的 Double 参数。我使用自定义的Formatter 来转换一个双精度值。 TextField 在编辑时会向Formatter 发送一个空字符串"",因此转换失败并且Double 参数不会更新。该结构是从具有@ObjectBinding 参数的父视图调用的,Double 是该对象的参数。

我目前正在使用 Xcode 11 beta 3 和 macOS Catalina Beta 3。如果参数是 String,则 TextField 有效。问题似乎是需要Formatter 的非字符串类型无法正确更新@Binding 值。 这是Formatter

public class DoubleFormatter: Formatter 

    override public func string(for obj: Any?) -> String? 
        var retVal: String?
        let formatter = NumberFormatter()
        formatter.numberStyle = .decimal

        if let dbl = obj as? Double 
            retVal = formatter.string(from: NSNumber(value: dbl))
         else 
            retVal = nil
        

        return retVal
    

    override public func getObjectValue(_ obj: AutoreleasingUnsafeMutablePointer<AnyObject?>?, for string: String, errorDescription error: AutoreleasingUnsafeMutablePointer<NSString?>?) -> Bool 

        var retVal = true

        if let dbl = Double(string), let objok = obj 
            objok.pointee = dbl as AnyObject?
            retVal = true
         else 
            retVal = false
        

        return retVal

    

这是在 TextField 中采用 Double 参数的 SwiftUI 视图

struct HStackTextTextField : View 
    var text: String
    @Binding var value: Double
    @State var valueState: Double

    var body: some View 
        HStack 
            Text("\(value)") //shows the value failing to update 
            TextField("Number", value: $value, formatter: DoubleFormatter()) //Still Fails
            Text("\(valueState)") //shows valueState updating properly
            TextField("Number", value: $valueState, formatter: DoubleFormatter()) //works as expected
        
    

我希望TextField 值在我键入时更新,但事实并非如此。当我跟踪格式化程序中的值时。提供给getObjectValue 的字符串是"",而不是TextField 中的值。

更新:从 catalina/Xcode beta 5 开始,当 View TextField 参数定义为 @Binding 并传递给 View 时,这似乎仍然是一个问题。如果 TextField 参数定义为 @State 并且是视图的本地参数,它似乎可以按预期工作。

【问题讨论】:

看起来这仍然是 Xcode 11 GM 2/macOS 10.15 Beta 8 的问题 一年多过去了,还是不行。 【参考方案1】:

我相信这是 SwiftUI 中的一个错误。 (见我的类似问题:SwiftUI TextField with formatter not working?)

在 beta 2 中,它根本不起作用。在 beta 3 中,我认为当(且仅当)您在输入字段后点击回车时,您会发现您的结果会被传递给格式化程序。希望在 Beta 4 中,他们将完成该错误的修复!

【讨论】:

我编辑了原始问题,因为问题似乎是 @Binding 无法与 TextField 和格式化程序一起正常工作

以上是关于SwiftUI TextField 绑定到 Double 不使用自定义格式化程序的主要内容,如果未能解决你的问题,请参考以下文章

SwiftUI TextField 绑定到 Double 不使用自定义格式化程序

SwiftUI如何让绑定到同一个状态的多个TextField呈现出不同输入行为

SwiftUI如何让绑定到同一个状态的多个TextField呈现出不同输入行为

使用 SwiftUI 中活动 TextField 中的值更新非活动 TextField

如何在 SwiftUI 中检测 TextField 的实时变化?

在 ForEach 循环中绑定时,如何阻止 SwiftUI TextField 失去焦点?