如何检测货币是否接受小数位?

How Can I Detect if Currency Accepts Decimal Digits?

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

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

到目前为止,一切都按预期进行。将方案的区域设置设置为使用不同的货币格式时,标签会正确填充。我在以下代码中检测货币符号的位置:

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
}

我删除了文本字段中的货币符号,只留下值,以及任何适用的货币小数点分隔符。该代码如下所示:

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
}

我 运行 遇到的问题是这对某些货币不起作用。例如,日元不使用小数,所以 let double = Double(integer) / 100 不起作用;结果总是 0。我尝试检测日元的货币小数点符号,但是当我使用 print(formatter.currencyDecimalSeparator) 打印出来时 Xcode 给了我 .。我曾期待一个空字符串,因为 NumberFormattercurrencyDecimalSeparator 属性 被显式展开,这意味着它不应该是 nil。我曾希望我可以使用 currencyDecimalSeparator 来确定我是否应该除以 100 以获得正确的值;分隔符会导致除法,而空 currencyDecimalSymbol 会跳过除法。

这是我把地区设置为日本时的场景:

这是我把地区设置为捷克时的场景:

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

查看 NumberFormatter maximumFractionDigitsminimumFractionDigits 属性以了解区域设置使用了多少小数位。

maximumFractionDigits 值很可能是您所需要的。将 10 乘以 maximumFractionDigits 的次方,您将得到除数。日元的价值应该是 0。10^0 当然是 1。美元和其他 maximumFractionDigits 为 2 的人会给你 10^2,当然是 100。