Introduction : Pourquoi "capturer" le changement de texte est essentiel ?
\n\nImaginez : vous développez une application de recherche de recettes. L'utilisateur commence à taper "pâtes", et votre recherche doit s'activer instantanément, sans appuyer sur un bouton. Ou vous créez un formulaire d'inscription où vous devez signaler l'erreur "mot de passe trop court" dès que l'utilisateur a tapé la troisième lettre.
\n\nDans les deux cas, vous devez connaître le moment précis où le texte dans UITextField a changé. Cette question sur Stack Overflow a recueilli des milliers de vues – et pour cause. Chaque développeur iOS y est confronté tôt ou tard.
\n\nEn 2025, nous avons au moins 4 façons de résoudre ce problème. Certaines sont des vétérans, ayant fait leurs preuves avec le temps. D'autres sont des approches récentes qu'Apple promeut activement. Dans cet article, nous allons passer en revue toutes les options, du classique au moderne, et je vous montrerai quelle méthode choisir pour une tâche spécifique.
\n\nC'est parti ! 🚀
\n\nMéthode 1. Target-Action : Ancienne mais efficace
\n\nLa méthode la plus simple et la plus compréhensible, qui fonctionne depuis iOS 2.0. Oui, elle a plus de 15 ans, mais elle est toujours d'actualité.
\n\nL'idée est que UITextField hérite de UIControl, et peut donc générer des événements. Celui qui nous intéresse est l'événement .editingChanged – il se déclenche à chaque modification du texte.
Exemple de code (UIKit + Storyboard ou en code)
\n\nimport UIKit\n\nclass ViewController: UIViewController {\n\n @IBOutlet weak var searchTextField: UITextField!\n\n override func viewDidLoad() {\n super.viewDidLoad()\n // Ajout d'une cible pour l'événement de changement de texte\n searchTextField.addTarget(self,\n action: #selector(textFieldDidChange(_:)),\n for: .editingChanged)\n }\n\n @objc func textFieldDidChange(_ textField: UITextField) {\n guard let text = textField.text else { return }\n print("Le texte a changé : \\(text)")\n // Ici, vous pouvez effectuer une recherche, une validation, etc.\n }\n}\n\nAvantages : code minimal, ne nécessite pas de souscrire à des protocoles, fonctionne rapidement.
\nInconvénients : nécessite l'utilisation de @objc – c'est du Swift legacy. Pas de contrôle fin (par exemple, impossible de distinguer une insertion de texte d'une suppression).
Méthode 2. Délégué UITextFieldDelegate : Contrôle sur chaque caractère
\n\nSi vous avez besoin non seulement de savoir que le texte a changé, mais aussi d'influencer le changement (bloquer la saisie, formater un numéro de téléphone), alors le délégué est votre choix.
\n\nLa méthode clé ici est textField(_:shouldChangeCharactersIn:replacementString:). Elle est appelée avant que le texte ne change réellement.
Exemple : formatage d'un numéro de téléphone
\n\nimport UIKit\n\nclass ViewController: UIViewController, UITextFieldDelegate {\n\n @IBOutlet weak var phoneTextField: UITextField!\n\n override func viewDidLoad() {\n super.viewDidLoad()\n phoneTextField.delegate = self\n }\n\n func textField(_ textField: UITextField,\n shouldChangeCharactersIn range: NSRange,\n replacementString string: String) -> Bool {\n\n // Autoriser uniquement les chiffres\n let allowedCharacters = CharacterSet.decimalDigits\n let characterSet = CharacterSet(charactersIn: string)\n guard allowedCharacters.isSuperset(of: characterSet) else {\n return false\n }\n\n // Limiter la longueur à 10 caractères\n let currentText = textField.text ?? ""\n guard let stringRange = Range(range, in: currentText) else { return false }\n let updatedText = currentText.replacingCharacters(in: stringRange, with: string)\n return updatedText.count <= 10\n }\n\n // En complément : capturer le moment où le texte a déjà changé\n func textFieldDidChangeSelection(_ textField: UITextField) {\n print("Texte mis à jour : \\(textFi