四舍五入货币值(SwiftUI,核心数据)

Rounding currency values (SwiftUI, Core Data)

我正在尝试在 SwiftUI 中创建一个简单的 TextField,它将提供的值格式化为货币的有效值。我需要将该值四舍五入为 2 位数。并使用核心数据存储舍入值(我知道该怎么做,我使用的是十进制类型,顺便说一句)。

到目前为止我有这个:

import SwiftUI

struct ContentView: View {
    @State private var newValueAsString = ""
    @State private var value: NSDecimalNumber = 0
    
    let decimalBehavior = NSDecimalNumberHandler(roundingMode: .plain, scale: 2, raiseOnExactness: false, raiseOnOverflow: false, raiseOnUnderflow: false, raiseOnDivideByZero: true)
    
    var body: some View {
        VStack {
            TextField("0", text: $newValueAsString, onCommit: {
                self.value = NSDecimalNumber(string: self.newValueAsString).rounding(accordingToBehavior: self.decimalBehavior)
                print("\(self.value)")
            }
            )
                .multilineTextAlignment(.trailing)
                .font(Font.system(size: 30))
                .keyboardType(.decimalPad)
            
            // Just to test. Later I will save the value to Core Data.
            Text("\(self.value)")
        }
        .padding()
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

问题

当 iOS 区域使用逗号而不是点时(例如,波兰),它无法正常工作。十进制键盘有“,”而不是“。”当我使用“,”时,数字没有正确四舍五入。 123,456 变为 123。使用点的区域(例如,美国)123.456 变为 123.46,如预期的那样。

我在这里错过了什么?我猜是 NumberFormatter,但我无法让它工作。

NSDecimalNumber 可以用字符串和语言环境初始化。 The documentation 明确提到区域设置用于解释小数点分隔符(强调我的):

locale : A dictionary (!) that defines the locale (specifically the decimalSeparator) to use to interpret the number in numericString.

所以你可以这样做:

// Here I am passing the current Locale but you should pass whatever makes sense to your input
self.value = NSDecimalNumber(string: self.newValueAsString, locale: Locale.current).rounding(accordingToBehavior: self.decimalBehavior)

示例:

print(NSDecimalNumber(string: "100.50", locale: Locale(identifier: "en_US"))) // => 100.5
print(NSDecimalNumber(string: "100,50", locale: Locale(identifier: "el_GR"))) // => 100.5