如何检测货币是否接受十进制数字?

尼克·科恩

我正在将用户输入格式化为货币。我有一个非常基本的视图控制器,其中包含两个标签和一个文本字段。场景是这样的:

Interface Builder 中视图控制器的屏幕截图

前导标签旨在为在值之前包含符号的货币显示货币符号。尾随标签旨在显示值后包含符号的货币的货币符号。文本字段水平扩展和收缩以适应输入的文本,以便尾随货币符号始终固定到输入的值。text未使用标签属性设置为nil使其显示为隐藏。

So far, everything works as expected. When setting the scheme's locale to use different currency formats, the labels are populated correctly. I am detecting the position of the currency symbol in the following code:

internal static var currencySymbolPosition: CurrencySymbolPosition {
    let currencyFormat = CFNumberFormatterGetFormat(CFNumberFormatterCreate(nil, Locale.current as CFLocale, .currencyStyle)) as NSString
    let positiveNumberFormat = currencyFormat.components(separatedBy: ";")[0] as NSString
    let currencySymbolLocation = positiveNumberFormat.range(of: "¤").location
    let position: CurrencySymbolPosition = currencySymbolLocation == 0 ? .start : .end
    return position
}

internal enum CurrencySymbolPosition {
    case start
    case end
}

I strip out the currency symbol in the text field, leaving only the value, with any applicable currency decimal separators. That code looks like this:

internal func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    guard let text = textField.text else { return false }
    guard let currencySymbol = formatter.currencySymbol else { return false }
    guard let decimalSeparator = formatter.currencyDecimalSeparator else { return false }
    guard let groupingSeparator = formatter.currencyGroupingSeparator else { return false }
    guard let newText = (text as NSString?)?.replacingCharacters(in: range, with: string) else { return false }
    let symbolsStripped = newText.replacingOccurrences(of: currencySymbol, with: "").replacingOccurrences(of: decimalSeparator, with: "").replacingOccurrences(of: groupingSeparator, with: "")
    guard let integer = Int(symbolsStripped) else { return false }
    let double = Double(integer) / 100
    guard let formatted = formatter.string(from: double as NSNumber) else { return false }
    textField.text = formatted.replacingOccurrences(of: currencySymbol, with: "").trimmingCharacters(in: .whitespaces)
    return false
}

The issue that I am running into is that this doesn't work for some currencies. For example, Japanese yen don't use decimals, so let double = Double(integer) / 100 doesn't work; the result is always 0. I tried detecting the currency decimal symbol of the yen, but Xcode gives me . when I print it out using print(formatter.currencyDecimalSeparator). I had expected an empty string since the currencyDecimalSeparator property of NumberFormatter is explicitly unwrapped, meaning that it shouldn't be nil. I had hoped that I could use the currencyDecimalSeparator to determine if I should divide by 100 to get the correct value; a separator would cause division while an empty currencyDecimalSymbol would skip the division.

This is what the scene looks like when I set the region to Japan:

显示日本货币格式的 iOS 模拟器屏幕截图

This is what the scene looks like when I set the region to Czech Republic:

显示捷克共和国货币格式的 iOS 模拟器屏幕截图

有没有办法确定哪些货币不使用小数,以便我可以在用户键入时正确设置文本字段的格式?

麦迪

查看NumberFormatter maximumFractionDigitsminimumFractionDigits属性以了解语言环境使用了多少个小数位。

maximumFractionDigits值很可能是您需要的。把 10 的次方maximumFractionDigits加上除数。日元的值应该为 0。10^0 当然是 1。美元和其他maximumFractionDigits值为 2 的人会给你 10^2,当然是 100。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章