2017-07-15 73 views
0

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

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。我试着检测日元的货币十进制符号,但是当我使用print(formatter.currencyDecimalSeparator)打印出来时,Xcode给了我.。由于NumberFormattercurrencyDecimalSeparator属性已被明确解开,因此我预计会有一个空字符串,这意味着它不应该是nil。我曾希望能用currencyDecimalSeparator来确定我是否应该用100除以得到正确的值;分隔符会导致分区,而空的currencyDecimalSymbol会跳过分区。

这是现场的样子,当我设置区日本:

Screenshot of iOS Simulator displaying currency format for Japan

这是现场的样子,当我设定的区域捷克共和国:

Screenshot of iOS Simulator displaying currency format for Czech Republic

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

+0

为什么要经历所有剥离所有的麻烦标点只是为了试图把它全部回来?只需删除货币符号,而不是别的。 – rmaddy

+0

@rmaddy我将文本字段格式化为使用类型,以便它们不需要显式输入小数。如果他们的区域设置不使用货币的小数点分隔符,那么货币应该从整数格式化。如果他们的区域设置使用货币的小数点分隔符,那么它应该从double中格式化。这样,两种货币格式都可以正确设置,而用户不必输入除数字以外的任何其他货币。我希望能更好地阐明我的意图。 –

回答

1

查看NumberFormattermaximumFractionDigitsminimumFractionDigits属性以了解语言环境使用的小数位数。

maximumFractionDigits值很可能是您需要的值。把10的权力maximumFractionDigits,你会得到你的除数。日元的价值应该是0. 10^0当然是1.美元和maximumFractionDigits为2的其他人会给你10^2这当然是100.

+0

这工作完美。我可以输入美元和其他相同格式的货币的小数,我只能输入不接受小数格式货币的整数。 –

相关问题