我正在努力将用户输入格式化为货币。我有一个非常基本的视图控制器,包含两个标签和一个文本字段。场景如下:
前导标签旨在显示包含值前符号的货币的货币符号。尾随标签用于显示包含值后面的符号的货币的货币符号。文本字段水平扩展和收缩以适合输入的文本,以便始终将尾随货币符号固定到输入的值。未使用标签的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
会跳过除法。
这是我将地区设置为日本时的场景:
这是我将该地区设置为捷克共和国时的情景:
有没有办法确定哪些货币不使用小数,以便我可以在用户输入时正确格式化文本字段?
答案 0 :(得分:1)
查看NumberFormatter
maximumFractionDigits
和minimumFractionDigits
属性,了解区域设置使用的小数位数。
maximumFractionDigits
值很可能是您所需要的。将10赋予maximumFractionDigits
的力量,你将获得你的除数。日元的值应为0. 10 ^ 0当然是1.美元和maximumFractionDigits
为2的其他人将给你10 ^ 2,当然是100。