9 Replies
      Latest reply on May 23, 2019 7:14 AM by garrett35
      garrett35 Level 1 Level 1 (0 points)

        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

        • Re: How to create a textField with numbers?
          jonprescott Level 2 Level 2 (70 points)

          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

            • Re: How to create a textField with numbers?
              jonprescott Level 2 Level 2 (70 points)

              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

            • Re: How to create a textField with numbers?
              jonprescott Level 2 Level 2 (70 points)

              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.

              • Re: How to create a textField with numbers?
                Claude31 Level 8 Level 8 (5,735 points)

                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

                • Re: How to create a textField with numbers?
                  eskimo Apple Staff Apple Staff (11,265 points)

                  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"

                    • Re: How to create a textField with numbers?
                      garrett35 Level 1 Level 1 (0 points)

                      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!

                        • Re: How to create a textField with numbers?
                          garrett35 Level 1 Level 1 (0 points)

                          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 ?? "")
                            • Re: How to create a textField with numbers?
                              eskimo Apple Staff Apple Staff (11,265 points)

                              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"