UITextField numeric bar: period instead of comma for float values

I am using a textField which is populated from a digital pad.

The problem is that with a lot of local formats (for example, in all European languages) the UITextField numeric panel has a period instead of a comma, so every time I write a decimal number, UITextField cannot recognize the decimal point and its rounded number; for example 23.07 becomes 23.

How can I solve this? I was thinking of installing a text filter set for the US; Is it possible? How?

I read the value using this:

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

      

+4


source to share


10 replies


Potential duplicate SO answer , useNSNumberFormatter

Swift example:

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

      



Example (Objective-C):

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

      

+13


source


Swift 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

      







Localized approach using NumberFormatter:

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

      




Playground testing

// User device 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

      

+15


source


Nobody solved the problem directly.

That is, the decimal separator is a convention for the locale.

iOS supports formatting numbers based on a specific locale.

If you work exclusively in this region, then everything should work correctly. The keyboard must accept numbers with the correct decimal separator.

If you are in most of Europe, for example, enter a comma as a separator with a decimal point. Period entry in these countries is incorrect. Someone from one of these countries would not do this because it is the wrong decimal separator. A European user will know to use a comma as a decimal separator and you don't have to do anything.

If you are in the United States, you must use the period. Using a comma in the US would be wrong.

A way of displaying a decimal number using number formatting. When you create a number formatter, it uses the current language by default.

If you need to convert a string containing a decimal number from one locale to another, you must use 2 number formatting. Use formatting in the original locale to convert the string to float. Then use the destination locale formatter to convert the number to a string in the output format.

Just create one number formatter in the current default locale and create a second formatted number and set it locally explicitly to the other locale you want to use.

+9


source


This is probably a duplicate of this answer , but since the original is in Objective-C, here's the Swift version:

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

      

+4


source


Since NSNumberFormatter was replaced by NumberFormatter in the latest version of Swift, I am happy to provide you with an updated possible solution:

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

      

+1


source


Swift 3: float or double value for string containing floating point

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
    }
}

      

Example:

"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

      

+1


source


The solution I found:

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

      

In my case, I tested with xcode and everything goes well, but when tested on a device, it crashed. That's because in Brazil we use the metric system, we separate the decimal ",". With this solution, it is automatically converted from comma to dot.

+1


source


Swift 4 solution, without using preferred languages, I had problems with fr_US and 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

      

0


source


You can convert it using NumberFormatter

and filtering different decimal separators:

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
}

      

0


source


        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)

      

Hope this helps you :)

-1


source







All Articles