【问题标题】:UITextField's numerical pad: dot instead of comma for float valuesUITextField 数字键盘:浮点值的点而不是逗号
【发布时间】:2015-07-20 23:07:16
【问题描述】:

我正在使用从数字键盘填充的文本字段。

麻烦的是,有很多本地区域格式(所有欧洲,例如),UITextField 的数字键盘有逗号而不是点,所以每次我写一个十进制数字,UITextField 无法识别十进制逗号和它的整数;例如 23,07 变成 23。

我该如何解决这个问题? 我想将 textField 设置为固定在美国;可能吗?怎么样?

我使用这个读取值:

var importo = (importoPrevistoTF.text as NSString).floatValue

【问题讨论】:

  • 显示您的代码。更多国家/地区使用十进制逗号。比小数点,请参阅:Decimal mark。哦,我不敢相信美国仍然不使用公制单位! ;-)
  • @zaph,总的来说,我们都是白痴。 :) 我们在学校里半心半意地教公制。加拿大做得对。从 70 年代初开始,他们干脆停止教孩子“帝王”系统并转换了。
  • @DuncanC 我们并不孤单,利比里亚和缅甸也不使用公制,仅此而已,就我们三个。
  • 添加了有问题的代码。我认为公制更智能,我只是不明白为什么不找到一个折衷方案来为每个人使用逗号或点...
  • 如果它是在 Swift 中,那将是重复的......

标签: ios swift uitextfield


【解决方案1】:

斯威夫特 4

extension String {
    static let numberFormatter = NumberFormatter()
    var doubleValue: Double {
        String.numberFormatter.decimalSeparator = "."
        if let result =  String.numberFormatter.number(from: self) {
            return result.doubleValue
        } else {
            String.numberFormatter.decimalSeparator = ","
            if let result = String.numberFormatter.number(from: self) {
                return result.doubleValue
            }
        }
        return 0
    }
}

"2.25".doubleValue // 2.25
"2,25".doubleValue // 2.25


使用 NumberFormatter 的本地化方法:

extension NumberFormatter {
    static let shared = NumberFormatter()
}
extension StringProtocol {
    var doubleValue: Double? {
        return NumberFormatter.shared.number(from: String(self))?.doubleValue
    }
}

游乐场测试

// User device's default settings for current locale (en_US)
NumberFormatter.shared.locale            // en_US (current)
NumberFormatter.shared.numberStyle       // none
NumberFormatter.shared.decimalSeparator  // "."
"2.7".doubleValue  // 2.7
"2,7".doubleValue  // nil
"$2.70".doubleValue  // nil

NumberFormatter.shared.numberStyle  = .currency
"2.7".doubleValue  // nil
"2,7".doubleValue  // nil
"$2.70".doubleValue  // 2.7


NumberFormatter.shared.locale  = Locale(identifier: "pt_BR") // pt_BR (fixed)
"2.7".doubleValue     // nil
"2,7".doubleValue     // nil
"R$2,70".doubleValue  // 2.7

NumberFormatter.shared.numberStyle = .none
"2.7".doubleValue      // nil
"2,7".doubleValue      // 2.7
"R$2,70".doubleValue   // nil

【讨论】:

【解决方案2】:

SO Answer 的可能重复项,使用 NSNumberFormatter

示例 Swift:

let number = NSNumberFormatter().numberFromString(numberString)
if let number = number {
    let floatValue = Float(number)
}

示例(Objective-C):

NSNumber *number = [[NSNumberFormatter new] numberFromString: numberString];
float floatValue = number.floatValue;

【讨论】:

  • 有一个奇怪的问题。对于某些区域格式,例如意大利语、点和逗号有效,但对于其他格式,例如美国,点有效但逗号崩溃;怎么可能?
【解决方案3】:

没有人真正直接解决过这个问题。

也就是说,小数点分隔符是区域设置的约定。

iOS 支持根据特定区域设置格式化数字。

如果您纯粹在给定的语言环境中工作,那么一切都应该正常工作。小键盘应接受带有正确小数分隔符的数字。

例如,如果您位于欧洲的大多数国家/地区,则需要输入逗号作为小数分隔符。在这些国家/地区输入一个点是错误的。来自这些国家之一的人不会这样做,因为它是错误的小数分隔符。欧洲用户会知道使用逗号作为小数点分隔符,而您无需执行任何操作。

如果您在美国,您会使用句号。在美国使用逗号是错误的。

显示十进制数的方式是使用数字格式化程序。创建数字格式化程序时,默认情况下它使用当前语言环境。

如果您需要将包含十进制数字的字符串从一种语言环境转换为另一种语言环境,则应使用 2 个数字格式化程序。在源语言环境中使用格式化程序将字符串转换为浮点数。然后使用带有目标语言环境的格式化程序将数字转换为输出格式的字符串。

只需在默认的当前语言环境中创建一个数字格式化程序,然后创建第二个数字格式化程序并将其语言环境显式设置为您要使用的其他语言环境。

【讨论】:

    【解决方案4】:

    它可能是 this answer 的复制品,但由于原件是在 Objective-C 中,这里是一个 Swift 版本:

    let label = "23,07"
    let formatter = NSNumberFormatter()
    let maybeNumber = formatter.numberFromString(label)
    if let number = maybeNumber {
        println(number)   // 23.07
    }
    

    【讨论】:

    • 非常感谢!我刚刚用 Swift 翻译完,然后我看到你回答了!
    • 问题是formatter.numberFromString(label) 可能返回nil,如果语言环境与字符串格式不匹配,它将返回nil。
    【解决方案5】:

    Swift 3:浮点或双精度值的字符串包含带逗号的浮点数

    extension String {
        var floatValue: Float {
            let nf = NumberFormatter()
            nf.decimalSeparator = "."
            if let result = nf.number(from: self) {
                return result.floatValue
            } else {
                nf.decimalSeparator = ","
                if let result = nf.number(from: self) {
                    return result.floatValue
                }
            }
            return 0
        }
    
        var doubleValue:Double {
            let nf = NumberFormatter()
            nf.decimalSeparator = "."
            if let result = nf.number(from: self) {
                return result.doubleValue
            } else {
                nf.decimalSeparator = ","
                if let result = nf.number(from: self) {
                    return result.doubleValue
                }
            }
            return 0
        }
    }
    

    例子:

    "5,456".floatValue //5.456
    "5.456".floatValue //5.456
    "5,456".doubleValue //5.456
    "5.456".doubleValue //5.456
    
    "5,456".doubleValue.rounded() //5
    "5,6".doubleValue.rounded() //6
    

    【讨论】:

      【解决方案6】:

      由于 NSNumberFormatter 在最新版本的 Swift 中被 NumberFormatter 取代,我很高兴与您分享升级后的可能解决方案:

      var numberFormatter: NumberFormatter()
      importo = Float(numberFormatter.number(from: importoPrevistoTF.text!)!)
      

      【讨论】:

        【解决方案7】:

        我找到的解决方案:

        let nf = NumberFormatter()
        nf.locale = Locale.current
        let numberLocalized = nf.number(from: txtAlcool.text!)
        

        在我的情况下,我在 xcode 上进行测试,一切正常,但是在设备上进行测试时,它崩溃了。都是因为在巴西我们使用公制,逗号分隔小数点“,”。使用此解决方案,它会自动从逗号转换为点。

        【讨论】:

          【解决方案8】:

          使用当前版本的 Swift 的代码:

          let amount = "8,35"
          
          var counter: Int = 0
          var noCommaNumber: String!
          for var carattere in (amount) {
              if carattere == "," { carattere = "." }
              if counter != 0 { noCommaNumber = "\(noCommaNumber ?? "\(carattere)")" + "\(carattere)" } else { noCommaNumber = "\(carattere)" } // otherwise first record will always be nil
              counter += 1
          }
          
          let importo = Float(noCommaNumber)
          

          【讨论】:

            【解决方案9】:

            Swift 4 解决方案,不使用preferredLanguages 我遇到了fr_US 和decimalPad 的问题

            extension String {
            
                 func number(style: NumberFormatter.Style = .decimal) -> NSNumber? {
                    return [[Locale.current], Locale.preferredLanguages.map { Locale(identifier: $0) }]
                        .flatMap { $0 }
                        .map { locale -> NSNumber? in
                            let formatter = NumberFormatter()
                            formatter.numberStyle = style
                            formatter.locale = locale
                            return formatter.number(from: self)
                    }.filter { $0 != nil }
                    .map { $0! }
                    .first
                }
            }
            
            textfield.text?.number()?.floatValue
            

            【讨论】:

            • 可选 - 一些:9.3000000000000007
            【解决方案10】:

            您可以使用NumberFormatter 并过滤不同的小数分隔符进行转换:

            func getDoubleFromLocalNumber(input: String) -> Double {
                var value = 0.0
                let numberFormatter = NumberFormatter()
                let decimalFiltered = input.replacingOccurrences(of: "٫|,", with: ".", options: .regularExpression)
                numberFormatter.locale = Locale(identifier: "EN")
                if let amountValue = numberFormatter.number(from: decimalFiltered) {
                    value = amountValue.doubleValue
                }
                return value
            }
            

            【讨论】:

              【解决方案11】:
                      let number                      =   NSNumberFormatter()
                      let locale                      =   NSLocale.currentLocale()
                      let decimalCode                 =   locale.objectForKey(NSLocaleDecimalSeparator) as! NSString
              
                      number.decimalSeparator = decimalCode as String
                      let result = number.numberFromString(textField.text!)
              
                      let value = NSNumberFormatter.localizedStringFromNumber(result!.floatValue, numberStyle: .DecimalStyle)
                      print(value)
              

              希望对你有帮助:)

              【讨论】:

                猜你喜欢
                • 2021-06-28
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2014-09-17
                • 1970-01-01
                • 2019-08-29
                • 1970-01-01
                相关资源
                最近更新 更多