gpt4 book ai didi

ios - 如何将 UILabel 文本格式化为特定于语言环境的 NSNumberFormatterStyle.DecimalStyle

转载 作者:搜寻专家 更新时间:2023-10-31 22:20:54 24 4
gpt4 key购买 nike

我有一个 UILabel 来显示输入文本(它有十进制数字)。我想要做的是,UILabel 文本可以根据语言环境显示。例如-

"1234.56" should be shown as "1,234.56" for US locale, "1.234,56" for DE (Germany) locale and so on.

以下是我为实现这一目标所做的工作-

NSNumberFormatter.numberStyle = NSNumberFormatterStyle.DecimalStyle
NSNumberFormatter.locale = NSLocale(localeIdentifier: language)
NSNumberFormatter.maximumFractionDigits = 16

let displayVal: Double = NSNumberFormatter.numberFromString(displayText.text!).doubleValue
displayText.text = NSNumberFormatter.stringFromNumber(displayVal)

其中 displayText 是显示输入的 UILabel

它工作正常,直到 4 位数字,即“1234”显示为“1,234”(对于美国语言环境)。但是一旦添加了第 5 位数字,nil 就返回了 displayVal 常量变量。

我可以从函数定义中猜到格式化 displayText 文本字符串失败,当 numberFromString 尝试按照美国格式格式化它时,它可能是“1,2345”语言环境但失败,因为这不符合美国语言环境格式。

谁能提出解决这个问题的方法或更好的实现方法?

最佳答案

您可以执行类似以下操作,即去掉任何千位分隔符,从中获取一个数字,然后使用千位分隔符重新格式化:

@IBAction func didEditingChanged(_ sender: UITextField) {
guard let text = sender.text else { return }

let formatter = NumberFormatter()
formatter.numberStyle = .decimal

// get thousands separator

let thousandsSeparator = formatter.groupingSeparator ?? ","

// strip thousands separators out

let stripped = String(text.filter { return String($0) != thousandsSeparator })

// now, re-insert them, if any

if let number = formatter.numberFromString(stripped) {
sender.text = formatter.stringFromNumber(number)
}
}

假设您将其连接到“编辑更改”以使其不断更新,这会引入一些问题。例如,要输入尾随小数位,您可能必须手动检查并允许保留:

@IBAction func didEditingChanged(_ sender: UITextField) {
guard let text = sender.text else { return }

let formatter = NumberFormatter()
formatter.numberStyle = .decimal

// get thousands separator

let thousandsSeparator = formatter.groupingSeparator ?? ","

// strip thousands separators out

let stripped = String(text.filter { return String($0) != thousandsSeparator })

// see if decimal place found, and if so, set fractional digits accordingly

let decimalSeparator = formatter.decimalSeparator ?? "."
var fractionalDigits: Int?
if let decimalSeparatorIndex = text.range(of: decimalSeparator)?.lowerBound {
fractionalDigits = text[decimalSeparatorIndex...].count(of: "0123456789")
formatter.minimumFractionDigits = fractionalDigits!
}

guard
let number = formatter.number(from: stripped),
var result = formatter.string(from: number)
else {
// do whatever is appropriate if string isn't a number at all
return
}

// re-add trailing decimal place only if decimal separator was found, but no fractional digits were

if fractionalDigits == 0 {
result += decimalSeparator
}

// update text field

sender.text = result
}

请注意,它使用了这个小扩展:

extension StringProtocol {
func count(of string: String) -> Int {
return reduce(0) { $0 + (string.contains($1) ? 1 : 0) }
}
}

您还可以进行许多其他改进。例如,如果用户在编辑时不在文本字段的末尾,这将重置 selectedTextRange。您可能还应该实现 shouldChangeCharactersIn 以确保您根本无法在 stripped 会失败的地方输入值。等等

但希望这说明了一种捕获文本输入并使用格式化的十进制数更新结果的方法。


有关 Swift 2 版本,请参阅 previous revision of this answer

关于ios - 如何将 UILabel 文本格式化为特定于语言环境的 NSNumberFormatterStyle.DecimalStyle,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38002898/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com