iOS
UITextField
text change event
Swift
event handling

UITextField text change event

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

If you want to react every time a UITextField changes, the most direct approach is to observe the .editingChanged control event. Other options exist, but the best choice depends on whether you want the updated text after the change or a chance to validate input before the change is applied.

Use .editingChanged for Post-Change Updates

The simplest way to respond as the user types is target-action with .editingChanged.

swift
1import UIKit
2
3final class SearchViewController: UIViewController {
4    private let textField = UITextField()
5
6    override func viewDidLoad() {
7        super.viewDidLoad()
8
9        textField.borderStyle = .roundedRect
10        textField.addTarget(self, action: #selector(textDidChange(_:)), for: .editingChanged)
11        view.addSubview(textField)
12    }
13
14    @objc private func textDidChange(_ sender: UITextField) {
15        print("Current text:", sender.text ?? "")
16    }
17}

This is usually the best answer for live search, inline validation messages, or enabling and disabling buttons based on current text.

Use the Delegate When You Need Pre-Change Control

If you need to block invalid characters or compute the proposed new text before it appears, use the delegate method shouldChangeCharactersIn.

swift
1extension SearchViewController: UITextFieldDelegate {
2    func textField(
3        _ textField: UITextField,
4        shouldChangeCharactersIn range: NSRange,
5        replacementString string: String
6    ) -> Bool {
7        let current = textField.text ?? ""
8        let nsCurrent = current as NSString
9        let updated = nsCurrent.replacingCharacters(in: range, with: string)
10
11        print("Proposed text:", updated)
12        return true
13    }
14}

This method runs before the text field updates its visible text, which makes it useful for validation rules such as maximum length or allowed characters.

NotificationCenter Works for Broader Observation

If you need to observe text changes from outside the immediate target-action flow, NotificationCenter is another option:

swift
1NotificationCenter.default.addObserver(
2    self,
3    selector: #selector(handleTextNotification(_:)),
4    name: UITextField.textDidChangeNotification,
5    object: textField
6)
7
8@objc private func handleTextNotification(_ notification: Notification) {
9    guard let field = notification.object as? UITextField else { return }
10    print("Notification text:", field.text ?? "")
11}

This is useful when several objects need to react, though it is usually more overhead than .editingChanged for a single field in one view controller.

Choose the Hook Based on Intent

A simple rule makes the API choice easier:

  • use .editingChanged when you want the current text after it updates
  • use the delegate when you want to validate or modify an edit before it is applied
  • use notifications only when several parts of the app need to observe the same field

That distinction keeps the code easier to understand than mixing all three patterns in one screen.

Common Pitfalls

The biggest mistake is using the delegate method when the real need is just "tell me the new text after it changed". For that, .editingChanged is simpler and clearer.

Another common issue is forgetting that shouldChangeCharactersIn gives you the replacement before the field updates. If you print textField.text directly inside that method, you will still see the old text unless you build the proposed value manually.

People also add observers through NotificationCenter and forget to manage them carefully in older code patterns. That is one reason target-action is often the most straightforward solution.

Finally, if your project uses MVVM, Combine, or another reactive layer, the text-field event may be bridged into a higher-level binding. Even then, it is still useful to understand the native UIKit event model underneath.

Summary

  • Use .editingChanged when you want the current text after each change.
  • Use the delegate method when you need to inspect or reject edits before they are applied.
  • Use NotificationCenter only when broader observation is actually useful.
  • Remember that delegate callbacks happen before the text field finishes updating its text.
  • Choose the mechanism based on whether you need post-change reaction or pre-change control.

Course illustration
Course illustration

All Rights Reserved.