How to create a textField with numbers?

Hey there,


I simply want a text field which can deal with numbers.

So theTextField.text should be a Double and not a String.


How can I do this in an easy way?


Converting like this does not work because the Double should be optional.

let double = Double(theTextField.text)


Best,

Garrett35

Accepted Reply

change to:

          let theText = theTextField.text ?? ""
          let double = Double(theText) ?? 0.0
          print("double", double)


Type 3, and get

double 3.0

Type 3A, and get

double 0.0

Replies

NSTextFields can already deal with numbers. An NSTextField inherits from NSControl, which has a .doubleValue property (set and get). Comparable extractors for floats, integers, int32, bool, as well as the string itself are also available

Looking at your message a little harder, you are probably trying to use a UITextField. You might be able to get away with:


let double = Double?(text)


otherwise:


guard let text = theTextField.text else {

<handle nil text>

}

let double = Double(text)


You might also want to look into the UITextFieldDelegate about validators, formatters, etc., to check for legal input if that is important

Actually, according to the Swift Language Reference, what you wrote should actually do what you want. if theTextField.text does not convert successfully to a double, a Double? should be returned, if I read the reference manual correctly. That would handle both the text being nil, as well as not being a legal Double string.

change to:

          let theText = theTextField.text ?? ""
          let double = Double(theText) ?? 0.0
          print("double", double)


Type 3, and get

double 3.0

Type 3A, and get

double 0.0

First up, the double-from-string initialiser is not internalisation savvy (for example, it always assumes that the decimal separater is dot, whereas in many European countries it’s comma), so it’s not appropriate for parsing strings that the user entered into a text field. If you’re just playing around it’s fine, but in a real app you’d want to look at

NumberFormatter
.

As to your actual problem, there’s two common ways around this. You can use the

??
to give the field a default value if it’s
nil
:
let d1 = Double(theTextField.text ?? "")

Or you can use

flatMap(_:)
to convert the value only if it’s not
nil
:
let d2 = theTextField.text.flatMap { Double($0) }

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Thank you very much for all your helpful answers!


I like Claude's way best because in this case for me it's important to distinguish between "not-set" and "invalid-input".


But what you said, eskimo, is in fact also very important I and didn't think on it up to now.

Where I live it is common to use doubles with a comma. So I would be insteresed in NumberFormatter. I loked up in the Dev Documentation but unfortunately there is no example so I don't know how exactly implement this.


Thank's for helping!

Sometimes it is surprising how fast you don't get an answer any more since the problem become a bit difficult.

Well, I gave you the points...


However, I fixed the problem myself by replacing and converting every "," to "."

So it is not important which format the user types in.


If someone is interesed in, here is the source code:

func isCommaInput(text: String) -> Double? {
        var convertDouble: [String] = []
        for i in text {
            if i == "," {
                convertDouble += ["."]
            } else {
                convertDouble += [String(i)]
            }
        }
        var convertedNumber = ""
        for i in convertDouble {
            convertedNumber.append(i)
        }
        let convertedDouble = Double(convertedNumber)
        return convertedDouble
    }


The function you uses like that:

double1 = isCommaInput(text: FirstInput.text ?? "")

Sometimes it is surprising how fast you don't get an answer any more since the problem become a bit difficult.

Sorry, but I didn’t notice your follow-up question. In future, you might think about putting separate questions in a separate thread, especially once you’ve marked the thread as resolved.

However, I fixed the problem myself by replacing and converting every "," to "."

There are easier ways to convert commas to dots. Here’s one that does it manually:

func convertCommasToDots(_ input: String) -> String {
    return String(input.map {
        $0 == "," ? "." : $0
    })
}

but my preferred approach is to use the high-level API:

func convertCommasToDots(_ input: String) -> String {
    return input.replacingOccurrences(of: ",", with: ".")
}

However, that’s not a great solution to this problem because there’s such a variety of different number formatting approaches around the world. The preferred option is to use

NumberFormatter
. Along those lines, you wrote:

I looked up in the Dev Documentation but unfortunately there is no example so I don't know how exactly implement this.

There is a lot of information about

NumberFormatter
out there, you just have to adjust your search parameters:
  • Much of Apple’s documentation hasn’t made the leap to the new documentation format. For example, Data Formatting Guide is full of useful tidbits about formatters. The code snippets are in Objective-C, not Swift, but the core concepts are all the same.

  • There’s a bunch of third-party resources out there. You’ll want to search for Swift NumberFormatter to prioritise Swift stuff, because many different environments use the name

    NumberFormatter
    for this. Also, make sure you only look at results from Swift 3 or later, because of the Swift Great Renaming.

Anyway, here’s a code snippet you get you started:

func numberFor(_ input: String) -> Double? {
    let nf = NumberFormatter()
    nf.numberStyle = .decimal
    return nf.number(from: input)?.doubleValue
}

This will do the right thing based on the user’s current locale. For example, it works equally well in

en_GB
(English as used in the UK) locale:
print(numberFor("1"))           // -> Optional(1.0)
print(numberFor("1.2"))         // -> Optional(1.2)
print(numberFor("12345.6"))     // -> Optional(12345.6)
print(numberFor("12,345.6"))    // -> Optional(12345.6)

and the

ar_PK
(Arabic as used in Pakistan) locale:
let one = "\u{0661}"
print(numberFor(one))                               // -> Optional(1.0)
let onePointTwo = "\u{0661}\u{066B}\u{0662}"
print(numberFor(onePointTwo))                       // -> Optional(1.2)
let oneTwoThreeFourFivePointSix = "\u{0661}\u{0662}\u{0663}\u{0664}\u{0665}\u{066B}\u{0666}"
print(numberFor(oneTwoThreeFourFivePointSix))       // -> Optional(12345.6)
let oneTwoCommaThreeFourFivePointSix = "\u{0661}\u{0662}\u{066C}\u{0663}\u{0664}\u{0665}\u{066B}\u{0666}"
print(numberFor(oneTwoCommaThreeFourFivePointSix))  // -> Optional(12345.6)

[Annoyingly, DevForums won’t let me post Arabic characters, so I had to use Unicode escaping in my second code snippet )-: If you want to see this example in its full glory, print the strings using Swift and then copy’n’paste the results into string literals.]

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Thank you, eskimo!