使用双值识别 SwiftUI TextField 中的更改

m8x*_*w3r 8 double commit textfield swiftui

我正在使用 TextField 让用户添加某物的价格。为了防止用户添加其他值作为数字,我将键盘类型更改为.decimalPad

stringValue每次角色更改时都会正确更新绑定。我现在的问题是doubleValue只有当用户按下回车键提交时才会更新。不幸的是,小数点键盘没有回车键来提交输入。因此,当我尝试在不按 Enter 键的情况下将值保存到核心数据对象时,会保存 0,而不是文本字段中的可见值(例如 17.12)。现在为了测试,我将使用另一种带有输入按钮的键盘类型,但对于生产来说,这需要以某种方式修复。

您有什么想法可以解决这个问题吗?下面是最小化的示例代码来显示问题。

struct ContentView: View {
@State private var doubleValue: Double = 0.0
@State private var stringValue = "Test"

private let numberFormatter: NumberFormatter = {
    let numberFormatter = NumberFormatter()
    numberFormatter.numberStyle = .currency
    return numberFormatter
}()

var body: some View {
    Form {
        TextField("", text: $stringValue)
            .disableAutocorrection(true)
        HStack {
            Text("Price")
            Spacer()
            TextField("", value: $doubleValue, formatter: numberFormatter)
                .fixedSize()
                .keyboardType(.decimalPad)
        }
        // show live value changes
        Text("\(stringValue)")
        Text("Value: \(doubleValue)")
    }
    .padding()
}
func saveToCoreData() {
    // save values into core data
}
}
Run Code Online (Sandbox Code Playgroud)

我正在使用 Xcode 12.2 和 MacOS BigSur 11.0.1。

编辑属于 asperis 评论:您的共享解决方案看起来相当不错,但正如您在屏幕截图中看到的那样,它的工作原理并不正确: 数字文本字段_测试

在初始设置值后,0我输入了 a 2,然后输入了 a 3。显示的值2.03确实不是我想要的。也许我可以增强你的提示方法。

小智 5

我有类似的问题。这是我实现的解决方案,因为如果它不是字符串,则无法检测到键入的值。这个想法是将值作为字符串,然后在进一步处理该值之前将其转换为 Double。如果传递 Double 值,则需要在将其绑定到 TextField 之前将其转换为 String。

struct SomeTextField: View {
    @State var string: String = ""
    @State var double: Double = 0.0
    
    func save() {
        double = Double(string)!
    }

    var body: some View {
        VStack {
            Text("String: \(string) Double: \(String(double))")
            TextField("0.00", text: $string).keyboardType(.decimalPad)
            Button(action: save) { Text("Save") }
        }
    }
        
Run Code Online (Sandbox Code Playgroud)


spn*_*nkr 3

在 iOS 15 上,您可以使用TextField ("Hello", value: $someDoubleValue, formatter: <your NumberFormatter here>)并且该值传播良好。

在 iOS 14 上,似乎无法使用格式化程序将a 绑定TextField到值。Double

因此,以下内容在 iOS 15 中工作正常,但在 iOS 14 中不起作用。

注意double 值嵌套在此处,因为这是取自我现在正在处理的代码片段。

public class MyViewModel: ObservableObject {
    @Published var child: ChildObject
}

public class ChildObject: Identifiable, ObservableObject {
    @Published var doubleValue: Double
}

public struct FancyPantsView: View {
     @ObservedObject var viewModel: MyViewModel

     public var body: some View {
          VStack {
               TextField ("Hello", value: $viewModel.child.doubleValue, formatter: amountFormatter)
                    .keyboardType(.decimalPad)
          }
     }

     let amountFormatter: NumberFormatter = {
          let formatter = NumberFormatter()
          formatter.zeroSymbol = ""
          return formatter
     }()
}

Run Code Online (Sandbox Code Playgroud)