1

I have a ViewController which inherits from UITextFieldDelegate and serves as the delegate for the text field in the view. I would like to trigger an action whenever the text is edited.

I tried implementing the textField method, which is listed in the UITextFieldDelegate documentation:

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool

The documentation describes this textField method as triggered when the text should be changed, which occurs before the specified text is changed. Here is the line from the documentation:

Asks the delegate if the specified text should be changed.

As this textField method triggers before the text is changed rather than after, the text available at textField.text therefore contains the prior text, not the new text updated after the change. To access the new text, I would need to apply the range and replacementString parameters to textField.text to imitate how the text will be changed.

Is there an alternative to the textField method that is triggered not when the text will be changed, but instead when the text has been changed? I'm thinking that directly using the text after the change would prevent me from having to hack an imitation of the change beforehand.

mherzl
  • 5,624
  • 6
  • 34
  • 75

4 Answers4

3

Add a target with a selector for valueChanged and you'll be able to get the events like you need here.

// adding target
textField.addTarget(self, action: #selector(textChanged), for: .valueChanged)
// selector
@objc func textChanged(_ textField: UITextField) {
    print(textField.text)
}
Frankenstein
  • 15,732
  • 4
  • 22
  • 47
  • I placed the 'adding target' bit to where it's called in `viewDidLoad`, and added that `textChanged` function as a method to the ViewController. Build succeeds and `addTarget` is called -- but the `textChanged` function is not called when text is changed, so I must be missing something. – mherzl Jul 28 '20 at 21:51
  • Make sure that you're adding it to the right `UITextField`. make sure that the `UITextField` `@IBOutlet` connection is not lost. – Frankenstein Jul 28 '20 at 21:56
  • 1
    the action type should be `.editingChanged` instead of `.valueChanged` – Mohamed Salah May 02 '23 at 15:48
2

Have you tried textDidChangeNotification? you will have to add observer for keyboarddidshow(notification). For ur Ref: https://stackoverflow.com/a/52325593

singhabhi13
  • 227
  • 1
  • 7
1

Just write extension UITextfieldDelegate to viewController, you will have these pre-defined functions:

func textFieldDidBeginEditing(_ textField: UITextField) {
        
}

func textFieldDidEndEditing(_ textField: UITextField) {
        
}

func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
        
}
Yaobin Then
  • 2,662
  • 1
  • 34
  • 54
Muhammad Aakif
  • 193
  • 2
  • 5
0

Just a tweak to Frankenstein's version which works correctly:

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

@objc func textChanged(_ textField: UITextField) {
        print(textField.text)
}
ibyte
  • 463
  • 4
  • 17