ios - 如何处理文本字段中的格式化数字(货币)?
问题描述
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)")
}
}
}
当我输入 RM12.34255 并按“返回”时,文本字段显示 RM12.34(格式为所需的小数)。但是,它不会将我的类属性更新为 RM12.34,而是将其更新为 RM12.34255。我该如何解决这个问题?
似乎货币标题(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
}
解决方案
关于问题 (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)")
}
}
}
我希望这有帮助。
推荐阅读
- java - 使用二分搜索查找数字的平方根
- javascript - v-for 不重新渲染数组 vue js
- virtualbox - FreeBSD 挂载失败并出现错误:设备不支持操作
- python - 为滚动函数的不同窗口在多列上找到更快的代码来实现 mean() 函数
- python - str.replace 返回 ValueError 漂亮的汤
- php - 添加自定义字体 mpdf-laravel
- angular - 来自 chokidar (C:\) 的错误:错误:EBUSY:资源繁忙或锁定,lstat 'C:\DumpStack.log.tmp
- python-3.x - 无法使用python运行while循环遍历csv文件
- c# - ddd 中聚合根模式中具有 Id 的 C# 复合键。为什么?
- javascript - 为什么 queryselectorAll 不能用于删除元素?