1

My app asks the user for a precise number of minutes which she/he inserts using a number pad keyboard. I'd like to block the keyboard's numbers >5 for the first number the user types (so that they can't type a number of minutes > 59). For the second number, I'd like it to unblock the previously blocked numbers so that the minutes can be precisely inserted (e.g. 18 or 59). Is there a way to do this? If so, how?

1 Answers1

1

You should work with textField(_:shouldChangeCharactersIn:replacementString:) from the UITextFieldDelegate.

Here is a working example of what you can do:

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

        var startString =  NSString()
        if textField.text != nil {
            startString = textField.text! as NSString
        }

        let endString = startString.stringByReplacingCharactersInRange(range, withString: string)

         if endString.isEmpty == true {
            return true
         }


        let intValue = Int(endString)
        if intValue >= 0 && intValue < 60 {
            return true
        }

        return false
    }

In this case, it will allow every integer value between 0 (included) and 60 (excluded).

Edit: This method is called by the UITextField on it's delegate (if you don't understand what is a delegate, take some time to read this and this, this pattern is very important).

So, to make the method above works, you just have to say to your UITextField that your UIViewController is its delegate. You can do it in the code (in viewDidLoad for example) or in Interface Builder. Here is a fully working example:

class MyViewController: UIViewController, UITextFieldDelegate {
    @IBOutlet weak var textField: UITextField!

    override func viewDidLoad() {
        super.viewDidLoad()
        textField.delegate = self
    }

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

        var startString = NSString()
        if textField.text != nil {
            startString = textField.text! as NSString
        }

        let endString = startString.stringByReplacingCharactersInRange(range, withString: string)

         if endString.isEmpty == true {
            return true
         }    

        let intValue = Int(endString)
        if intValue >= 0 && intValue < 60 {
            return true
        }

        return false
    }
}
Community
  • 1
  • 1
Julien Quere
  • 2,407
  • 16
  • 21
  • How would I then call this function? I don't really know what I should write. Thanks. – Bossvanlindt Aug 18 '16 at 05:20
  • I edited my answer with informations about the delegation :) – Julien Quere Aug 18 '16 at 06:45
  • Cool thanks. Now it doesn't allow any number higher than 59. However, for some reason, it doesn't allow the user to delete the very first number (e.g. the 5 in 53). Why does it do that? And how can it be solved? Btw I think I now understand delegates a bit better. Thanks. – Bossvanlindt Aug 18 '16 at 07:23
  • You just have to check if `endString.length == 0` and return true in this case. I just edited my answer. – Julien Quere Aug 18 '16 at 07:26
  • You're welcome. Please, mark this question as solved if it's the case :) – Julien Quere Aug 18 '16 at 07:36