【问题标题】:how to deal with formatted number (currency) in textfield?如何处理文本字段中的格式化数字(货币)?
【发布时间】:2020-06-12 08:44:53
【问题描述】:
struct PriceField: View {


    @ObservedObject var textFieldManager = TextFieldManager()
    @State var number : Double = 0
    @State var inputString  = ""


    var body: some View {


        HStack{
//            Text(format(num: textFieldManager.number))
            Text("\(textFieldManager.number)")
            TextField("RM", value: $textFieldManager.number, formatter: NumberFormatter.currency){
                    UIApplication.shared.endEditing()
            }

            .multilineTextAlignment(.trailing)
//            .keyboardType(.numberPad)



        }
    }
}


extension NumberFormatter {
    static var currency: NumberFormatter {
        let formatter = NumberFormatter()
        formatter.numberStyle = .currency
        formatter.locale = Locale(identifier: "ms_MY")
        return formatter
    }

}




func format(num: Double) -> String{
    let formatter = NumberFormatter()
    formatter.locale = Locale(identifier: "ms_MY")
    formatter.numberStyle = .currency

    if let formattedAmount = formatter.string(from: num as NSNumber) {
        return formattedAmount
    }
    else{
        return "Formatting error ... "
    }

}



class TextFieldManager: ObservableObject {

    @Published var number : Double = 0 {
        didSet{
            print("change from:", oldValue, "to:", "\(number)")
        }

    }


}
  1. 当我输入 RM12.34255 并按“返回”时,文本字段显示 RM12.34(格式为所需的小数)。然而,它 没有将我的班级财产更新为 RM12.34,而是得到 更新为 RM12.34255。我该如何解决这个问题?

  2. 似乎货币名称(RM)可以被删除并且有一个 用户可以输入没有当前符号的数字的机会 它会产生错误“MultiLineTextView[31301:771480] [SwiftUI] 值“12.34255”无效。”。是否可以使文本 文本字段中的“RM”不可擦除?

更新代码:

func format(num: Double) -> Double{
    let doubleStr = String(format: "%.2f", num) // "3.14"
    let doubleNum =  Double(doubleStr)!
    print("doubleStr \(doubleStr), doubleNum \(doubleNum)")
    return doubleNum

}



class TextFieldManager: ObservableObject {

    @Published var number : Double = 0 {
        didSet{
            print("change from:", oldValue, "to:", "\(number)")
            formattedNumber = format(num: number)
            print("formattedNumber is : \(formattedNumber)")

        }


    }

    @Published var formattedNumber : Double = 0



}

【问题讨论】:

    标签: ios swift swiftui number-formatting


    【解决方案1】:

    关于问题 (1),请理解格式化只会改变数字的“外观”,如 TextField 所示。它不会改变值。该值仍然是 Double。这就是为什么您的类属性“数字”将是双精度数。 我该如何解决这个问题?你没有,这是正常行为。要以您想要的方式显示此类属性“数字”,请使用 NumberFormatter 或您想要的任何格式化程序。

    关于问题(2),尝试“formatter.isLenient = true”,如下代码所示。

    这是我用来测试的代码。

    import SwiftUI
    
    struct ContentView: View {
    var body: some View {
       PriceField()
    }
    }
    
    struct PriceField: View {
    @ObservedObject var textFieldManager = TextFieldManager()
    var body: some View {
        HStack {
            Text("\(textFieldManager.number)")
            TextField("RM", value: $textFieldManager.number, formatter: NumberFormatter.currency)
        }
    }
    }
    
    extension NumberFormatter {
    static var currency: NumberFormatter {
        let formatter = NumberFormatter()
        formatter.isLenient = true  //  <--- works without the currency symbol
        formatter.numberStyle = .currency
        formatter.locale = Locale(identifier: "ms_MY")
        return formatter
    }
    }
    
    func format(num: Double) -> String{
    let formatter = NumberFormatter()
    formatter.locale = Locale(identifier: "ms_MY")
    formatter.numberStyle = .currency
    if let formattedAmount = formatter.string(from: num as NSNumber) {
        return formattedAmount
    } else {
        return "Formatting error ... "
    }
    }
    
    class TextFieldManager: ObservableObject {
    @Published var number : Double = 0 {
        didSet{
            print("---> change from:", oldValue, "to:", "\(number)")
        }
    }
    }
    

    我希望这会有所帮助。

    【讨论】:

    • 对于问题(1),好的,我明白了。所以我只是在'number'之上创建另一个类属性'formattedNumber'来解决这个问题。对于问题(2),嗯,这行得通。难道真的没有办法让货币符号在这里,而不是一直被抹去吗?
    • 添加 formatter.isLenient = true 使当前符号在按下“返回”按钮后重新出现,如果它在编辑过程中被删除。但是,在用户编辑文本字段期间保留符号可能是一个理想的属性
    • 处理货币符号的一种方法是在 TextField("", ...) 中不放置任何内容,并在其前面放置一个永久 Text("RM")。
    • 我刚试过,没用。你介意展示一下你是怎么做到的吗?顺便说一句,文本字段对齐在尾随。 Text("RM") TextField("", value: $textFieldManager.number, formatter: NumberFormatter.currency) { UIApplication.shared.endEditing() } .multilineTextAlignment(.trailing)
    • 这样的; HStack { Spacer() Text("RM") TextField("", value: $textFieldManager.number, formatter: NumberFormatter()) }
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-09-15
    • 1970-01-01
    • 1970-01-01
    • 2022-11-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多