How do I check when a UITextField changes?

I am trying to check when a text field changes, equivalent too the function used for textView - textViewDidChange so far I have done this:

  func textFieldDidBeginEditing(textField: UITextField) {
        if self.status.text == "" && self.username.text == "" {
            self.topRightButton.enabled = false
        } else {   
            self.topRightButton.enabled = true
        }
    }

Which kind of works, but the topRightButton is enabled as soon as the text field is pressed on, I want it to be enabled only when text is actually typed in?


Solution 1:

SWIFT

Swift 4.2

textfield.addTarget(self, action: #selector(ViewController.textFieldDidChange(_:)), for: .editingChanged)

and

@objc func textFieldDidChange(_ textField: UITextField) {

}

SWIFT 3 & swift 4.1

textField.addTarget(self, action: #selector(ViewController.textFieldDidChange(_:)), for: .editingChanged)

and

func textFieldDidChange(_ textField: UITextField) {

}

SWIFT 2.2

textField.addTarget(self, action: #selector(ViewController.textFieldDidChange(_:)), forControlEvents: UIControlEvents.EditingChanged)

and

func textFieldDidChange(textField: UITextField) {
    //your code
}

OBJECTIVE-C

[textField addTarget:self action:@selector(textFieldDidChange:) forControlEvents:UIControlEventEditingChanged];

and textFieldDidChange method is

-(void)textFieldDidChange :(UITextField *) textField{
    //your code
}

Solution 2:

You can make this connection in interface builder.

  1. In your storyboard, click the assistant editor at the top of the screen (two circles in the middle). Assistant editor selected

  2. Ctrl + Click on the textfield in interface builder.

  3. Drag from EditingChanged to inside your view controller class in the assistant view. Making connection

  4. Name your function ("textDidChange" for example) and click connect. Naming function

Solution 3:

Swift 5.0

textField.addTarget(self, action: #selector(ViewController.textFieldDidChange(_:)),
                          for: .editingChanged)

and handle method:

@objc func textFieldDidChange(_ textField: UITextField) {

}

Swift 4.0

textField.addTarget(self, action: #selector(ViewController.textFieldDidChange(_:)),
                          for: UIControlEvents.editingChanged)

and handle method:

@objc func textFieldDidChange(_ textField: UITextField) {

}

Swift 3.0

textField.addTarget(self, action: #selector(textFieldDidChange(textField:)), for: .editingChanged)

and handle method:

func textFieldDidChange(textField: UITextField) { 

}

Solution 4:

The way I've handled it so far: in UITextFieldDelegate

func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool
{
    // text hasn't changed yet, you have to compute the text AFTER the edit yourself
    let updatedString = (textField.text as NSString?)?.stringByReplacingCharactersInRange(range, withString: string)

    // do whatever you need with this updated string (your code)


    // always return true so that changes propagate
    return true
}

Swift4 version

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    let updatedString = (textField.text as NSString?)?.replacingCharacters(in: range, with: string)
    return true
}

Solution 5:

Swift 3

 textField.addTarget(self, action: #selector(ViewController.textFieldDidChange(sender:)), for: UIControlEvents.editingChanged)