在iOS上获取小数点键盘的小数点分隔符

Pal*_*lle 10 uikit foundation ios

我试图找出iOS中十进制键盘键盘使用的小数点分隔符,因此我可以将用户输入的字符串转换为带有NumberFormatter和返回的数字.

由于我想用现有值预先填充文本字段,我需要一个数字格式化程序,它使用与十进制键盘相同的小数点分隔符.


我的设备设置的语言(德语,德国)使用逗号作为小数分隔符.我已将iOS配置为将德语键盘作为主键盘和活动键盘以及英语(US,QWERTY)作为辅助键盘.

我正在处理的应用程序只有一个基础本地化,这是英语.在方案设置中,区域和语言设置为系统默认值.

如果我运行我的应用程序,小数键盘键盘使用的小数分隔符是".",这是en-US键盘使用的小数分隔符,但不是de-DE键盘.普通的字母键盘显示德语键盘布局.

如果我在iOS设备上删除了en-US键盘,则小数点分隔符将更改为",".


如何可靠地找出小数位键盘使用哪个小数点分隔符?

到目前为止,我尝试过的解决方案都没有工作:

  • 使用预设decimalSeparatorNumberFormatter总是给人"".
  • 使用Locale.current.decimalSeparator始终返回",".
  • 使用textField.textInputMode?.primaryLanguage弄清楚语言环境总是返回de-DE.
  • 使用Bundle.main.preferredLocalizations找出由应用程序总是返回使用的本地化en.

这是数字格式化程序的配置方式:

let numberFormatter = NumberFormatter()
numberFormatter.minimumIntegerDigits = 1
numberFormatter.minimumFractionDigits = 0
numberFormatter.maximumFractionDigits = 2
Run Code Online (Sandbox Code Playgroud)

编辑:似乎可以通过查找活动文本输入模式和应用程序本地化之间的匹配来确定小数位垫使用的区域设置:

let inputLocales = UITextInputMode.activeInputModes.compactMap {$0.primaryLanguage}.map(Locale.init(identifier:))
let localizations = Bundle.main.preferredLocalizations.map(Locale.init(identifier:))

let locale = inputLocales.flatMap { l in localizations.map {(l, $0)}}
    .filter { preferredLanguage, preferredLocalization in
        if preferredLocalization.regionCode == nil || preferredLanguage.regionCode == nil {
            return preferredLanguage.languageCode == preferredLocalization.languageCode
        } else {
            return preferredLanguage == preferredLocalization
        }
    }
    .first?.0
    ?? Locale.current

numberFormatter.locale = locale
Run Code Online (Sandbox Code Playgroud)

然而,该解决方案有几个缺点:

  1. 我不知道UIKit是否正是这样选择小数分隔符.某些语言的行为可能不同
  2. 每次格式化数字时都必须计算,因为用户可以在应用程序运行时更改键盘.

Erl*_*end 2

我的经验是,当您仅支持英语本地化时,小数键盘类型中的小数分隔符将始终为.en_US因此,在NumberFormatter从字符串中解析数字时,您需要强制使用语言环境。

这是一个代码片段,它尝试首先使用 进行解析en_US,然后尝试使用 进行解析Locale.current

func parseNumber(_ text:String) -> Double? {

    // since we only support english localization, keyboard always show '.' as decimal separator,
    // hence we need to force en_US locale
    let fmtUS = NumberFormatter()
    fmtUS.locale = Locale(identifier: "en_US")
    if let number = fmtUS.number(from: text)?.doubleValue {
        print("parsed using \(fmtUS.locale)")
        return number
    }

    let fmtCurrent = NumberFormatter()
    fmtCurrent.locale = Locale.current
    if let number = fmtCurrent.number(from: text)?.doubleValue {
        print("parsed using \(fmtCurrent.locale)")
        return number
    }

    print("can't parse number")
    return nil
}
Run Code Online (Sandbox Code Playgroud)

如果 Apple 将小数分隔符添加为小数键盘类型的小数分隔符,我将不胜感激,Locale.current否则我们需要为所有区域设置添加本地化才能正确实现这一点。