我正在将用户输入格式化为货币。我有一个非常基本的视图控制器,其中包含两个标签和一个文本字段。这个场景是这样的:如何检测货币是否接受小数位?
领先的标签是为了显示包含前值符号货币货币符号。尾部标签旨在显示包含符号后面的符号的货币的货币符号。文本字段水平扩展和缩小以适应输入的文本,以便拖尾货币符号始终固定为输入值。未使用标签的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给了我.
。由于NumberFormatter
的currencyDecimalSeparator
属性已被明确解开,因此我预计会有一个空字符串,这意味着它不应该是nil
。我曾希望能用currencyDecimalSeparator
来确定我是否应该用100除以得到正确的值;分隔符会导致分区,而空的currencyDecimalSymbol
会跳过分区。
这是现场的样子,当我设置区日本:
这是现场的样子,当我设定的区域捷克共和国:
有没有办法确定哪些货币不使用小数,以便我可以正确地格式化文本字段为用户键入?
为什么要经历所有剥离所有的麻烦标点只是为了试图把它全部回来?只需删除货币符号,而不是别的。 – rmaddy
@rmaddy我将文本字段格式化为使用类型,以便它们不需要显式输入小数。如果他们的区域设置不使用货币的小数点分隔符,那么货币应该从整数格式化。如果他们的区域设置使用货币的小数点分隔符,那么它应该从double中格式化。这样,两种货币格式都可以正确设置,而用户不必输入除数字以外的任何其他货币。我希望能更好地阐明我的意图。 –