带有格式化程序的

带有格式化程序的

本文介绍了带有格式化程序的 SwiftUI TextField 不起作用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试更新数字字段,因此我将 TextField 与 formatter: 参数集一起使用.它将数字格式化到输入字段中就好了,但在编辑时不会更新绑定值.在没有指定格式化程序的情况下,TextField 工作正常(在字符串上).这是一个错误还是我遗漏了什么?

I'm trying to get a numeric field updated so I'm using a TextField with the formatter: parameter set. It formats the number into the entry field just fine, but does not update the bound value when edited. The TextField works fine (on Strings) without the formatter specified. Is this a bug or am I missing something?

更新:从 Xcode 11 beta 3 开始,它可以正常工作.现在,如果您编辑数字 TextField,则在您按回车键后会更新绑定值.每次按键后,字符串文本字段仍会更新.我猜他们不想在每次按键时将要格式化的值发送到格式化程序,或者可能存在/将会有一个 TextField 修饰符来告诉它这样做.

UPDATE: As of Xcode 11 beta 3 it kind of works. Now if you edit the numeric TextField, the bound value is updated after you hit return. The String TextField is still updated after each keypress. I guess they don't want to send the value to be formatted to the formatter with every key press, or maybe there is/will be a modifier for TextField to tell it to do that.

请注意 API 略有变化;旧的 TextField init() 已弃用,并添加了新的 titleKey String 字段作为第一个参数,该参数在字段中显示为占位符文本.

Note that The API has changed slightly; the old TextField init()s are deprecated and a new titleKey String field has been added as the first parameter which appears as placeholder text in the field.

struct TestView : View {
   @State var someText = "Change me!"
   @State var someNumber = 123.0
   var body: some View {
       Form {
            // Xcode 11 beta 2
            // TextField($someText)
            // TextField($someNumber, formatter: NumberFormatter())
            // Xcode 11 beta 3
            TextField("Text", text: $someText)
            TextField("Number", value: $someNumber, formatter: NumberFormatter())
            Spacer()
            // if you change the first TextField value, the change shows up here
            // if you change the second (the number),
            // it does not *until you hit return*
            Text("text: \(self.someText), number: \(self.someNumber)")
            // the button does the same, but logs to the console
            Button(action: { print("text: \(self.someText), number: \(self.someNumber)")}) {
                Text("Log Values")
            }
        }
    }
}

如果您输入第一个(字符串)TextField,Text 视图中的值会立即更新.如果您编辑第二个(数字),则什么也不会发生.同样,点击按钮会显示字符串的更新值,但不会显示数字.我只在模拟器中试过这个.

If you type in the first (String) TextField, the value in the Text view is updated immediately. If you edit the second (Numeric), nothing happens.Similarly tapping the Button shows an updated value for the String, but not the number. I've only tried this in the simulator.

推荐答案

可以使用 Binding 来转换 DoubleString for TextField

You can use Binding to convert Double<-->String for TextField

struct TestView: View {
    @State var someNumber = 123.0

    var body: some View {
        let someNumberProxy = Binding<String>(
            get: { String(format: "%.02f", Double(self.someNumber)) },
            set: {
                if let value = NumberFormatter().number(from: $0) {
                    self.someNumber = value.doubleValue
                }
            }
        )

        return VStack {
            TextField("Number", text: someNumberProxy)

            Text("number: \(someNumber)")
        }
      }
}

您可以使用计算属性的方式来解决这个问题.(感谢@iComputerfreak)

You can use computed property way to solve this issue. (thanks @ iComputerfreak)

struct TestView: View {
    @State var someNumber = 123.0

    var someNumberProxy: Binding<String> {
        Binding<String>(
            get: { String(format: "%.02f", Double(self.someNumber)) },
            set: {
                if let value = NumberFormatter().number(from: $0) {
                    self.someNumber = value.doubleValue
                }
            }
        )
    }

    var body: some View {
        VStack {
            TextField("Number", text: someNumberProxy)

            Text("number: \(someNumber)")
        }
      }
}

这篇关于带有格式化程序的 SwiftUI TextField 不起作用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-22 12:59