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

时间:2017-07-15 03:01:04

标签: ios currency-formatting

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

Screenshot of view controller in Interface Builder

前导标签旨在显示包含值前符号的货币的货币符号。尾随标签用于显示包含值后面的符号的货币的货币符号。文本字段水平扩展和收缩以适合输入的文本,以便始终将尾随货币符号固定到输入的值。未使用标签的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。我尝试检测日元的货币小数符号,但是当我使用.将其打印出来时,Xcode会给我print(formatter.currencyDecimalSeparator)。我原本期望一个空字符串,因为currencyDecimalSeparator的{​​{1}}属性被明确解开,这意味着它不应该是NumberFormatter。我曾希望我可以使用nil来确定是否应该除以100以获得正确的值;分隔符会导致除法,而空currencyDecimalSeparator会跳过除法。

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

Screenshot of iOS Simulator displaying currency format for Japan

这是我将该地区设置为捷克共和国时的情景:

Screenshot of iOS Simulator displaying currency format for Czech Republic

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

1 个答案:

答案 0 :(得分:1)

查看NumberFormatter maximumFractionDigitsminimumFractionDigits属性,了解区域设置使用的小数位数。

maximumFractionDigits值很可能是您所需要的。将10赋予maximumFractionDigits的力量,你将获得你的除数。日元的值应为0. 10 ^ 0当然是1.美元和maximumFractionDigits为2的其他人将给你10 ^ 2,当然是100。