首页 > 解决方案 > 如何处理文本字段中的格式化数字(货币)?

问题描述

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



}

标签: iosswiftswiftuinumber-formatting

解决方案


关于问题 (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)")
    }
}
}

我希望这有帮助。


推荐阅读