0

Additional question:

Still need some help with my code. The textfield is 'measuredValue' and I plan to have 30 different texfields (measuredValue1...30). When I type '923' the text will be set to '9.23' right away. Then I want to add '4'... for '92.34' but that doesn't work. Thanks for helping out.

func textField(textField: UITextField,
shouldChangeCharactersInRange range: NSRange,
replacementString string: String)
-> Bool {

    if count(string) == 0 { return true }

    var measuredValue = (textField.text as NSString).stringByReplacingCharactersInRange(range, withString: string)

    switch textField {

    case digitsOnlyTextField:

        if count(measuredValue) == 3  || count(measuredValue) == 4 {
            let stringNumeric = Double(measuredValue.toInt()!) / 100
            measuredValue = String(format:"%.2f", stringNumeric)
            digitsOnlyTextField.text = measuredValue
        }

        return measuredValue.containsOnlyCharactersIn("0123456789") && count(measuredValue) <= 4

    default:
        return true
    }

}

Original question:

I would like to validate my text fields to get the right input for my app. Input needs to be formatted like '9.90' or '15.34'. So always 3 or 4 digits, and always 2 decimals.

I would like to use 'numberpad keyboard' (just 0...9, no point) and add the decimal point after the user exits the field. So the user input is 990 or 1534, and then in the text field it will become 9.90 or 15.34 automatically.

I tried searching for examples first, but didn't find what I was looking for. Any help appreciated. Jan

arakweker
  • 1,535
  • 4
  • 18
  • 40
  • You should probably add a dot as the user is typing for better visual feedback. – Sergey Kalinichenko May 09 '15 at 09:59
  • NSNumberFormatter has many cool features. But I agree with the comment above. So use a textfield delegate method to help get that done. – DogCoffee May 09 '15 at 10:00
  • I answered on similar question that might help you (using mask): http://stackoverflow.com/questions/19576202/angular-input-field-with-a-currency-mask-directive-for-money-format-on-the-fly/19576763#19576763 – Maxim Shoustin May 09 '15 at 10:18
  • possible duplicate of [How move a string to right on left?](http://stackoverflow.com/questions/29782982/how-move-a-string-to-right-on-left) – Leo Dabus May 09 '15 at 10:19
  • Thanks for the advises... used some of them! – arakweker May 10 '15 at 07:36

2 Answers2

0

You have to implement the UITextField delegate method

func textFieldDidEndEditing(textField: UITextField) {
    //Logic goes here....
    var textString = textField.text as! String
    let textLength = countElements(textString)
    if textLength >= 3 && textLength <= 4 {
        let stringNumeric = Double(textString.toInt()!) / 100
        let texts = String(format:"%.2f", stringNumeric)
        textField.text = texts
    }
}

Your class should confirm to the protocol UITextFieldDelegate

Amit89
  • 3,000
  • 1
  • 19
  • 27
  • I tested in Xcode6.1.1, if you are running Swift1.2 you may get warnings. – Amit89 May 09 '15 at 11:16
  • Thanks Amit89. It's all new for me but I'm learning fast. It is almost working... struggling a bit with when the dot is showing up (as what dasblinkenlight advised). I'll let you know when I finished my code, I appreciate your help! – arakweker May 10 '15 at 07:34
0

this is the 'final' code I used (but I'm open for improvements!). A few remarks:

  1. when a user clicks the background (and leaves the textfield) the decimal point gets set.
  2. when a user copies & pastes text from another app, this code handles that.
  3. when a user goes back in the textfield for editing, the decimal point gets set again.
  4. Deleting a value (to an empty textfield) is handled correctly.

So I'm pleased. Thanks for the help.

import UIKit

class ViewController: UIViewController, UITextFieldDelegate {

@IBOutlet weak var numberField: UITextField!

  override func viewDidLoad() {
super.viewDidLoad()
numberField.delegate = self
numberField.keyboardType = UIKeyboardType.NumberPad
}

override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}

// Tap background to add decimal point and defocus keyboard

@IBAction func userTappedBackground(sender: AnyObject) {
for view in self.view.subviews as! [UIView] {
  if let textField = view as? UITextField {
    if count(numberField.text) > 0 {
        var numberString = numberField.text
        numberString = numberString.stringByReplacingOccurrencesOfString(".", withString: "", options: NSStringCompareOptions.LiteralSearch, range: nil)
        var numberFromString = Double(numberString.toInt()!) / 100
        numberField.text = String(format:"%.2f", numberFromString)
    }
    textField.resignFirstResponder()
  }
}
}

func textField(textField: UITextField,
    shouldChangeCharactersInRange range: NSRange,
    replacementString string: String)
    -> Bool {
        var result = true
        var prospectiveText = (textField.text as NSString).stringByReplacingCharactersInRange(range, withString: string)
        prospectiveText = prospectiveText.stringByReplacingOccurrencesOfString(".", withString: "", options: NSStringCompareOptions.LiteralSearch, range: nil)
        if textField == numberField {
            if count(string)>0 {
                let disallowedCharacterSet = NSCharacterSet(charactersInString: "0123456789").invertedSet
                let replacementStringIsLegal = string.rangeOfCharacterFromSet(disallowedCharacterSet) == nil
                 let resultingStringLengthIsLegal = count(prospectiveText) <= 4
                let scanner = NSScanner(string: prospectiveText)
                let resultingTextIsNumeric = scanner.scanDecimal(nil) && scanner.atEnd
                result = replacementStringIsLegal && resultingStringLengthIsLegal && resultingTextIsNumeric
            }
        }
        return result
}
arakweker
  • 1,535
  • 4
  • 18
  • 40