Responder Chain est un mécanisme iOS qui transmet séquentiellement les événements tactiles, les pressions sur les touches et les gestes à travers la hiérarchie des objets UIResponder jusqu'à ce que l'un d'eux traite l'événement. La chaîne commence avec l'objet qui a détecté l'événement et remonte la hiérarchie : de la vue à sa superview, puis au contrôleur de vue, à la fenêtre et enfin à UIApplication. Selon la Apple Developer Documentation (2026), ce modèle permet de séparer la responsabilité du traitement des événements entre les composants de l'interface, offrant une flexibilité sans liaison rigide à un gestionnaire spécifique.
Points clés
Responder Chain est une séquence d'objets UIResponder à travers laquelle iOS transmet les événements d'entrée tels que les touches, les pressions sur les touches et les données de l'accéléromètre. Chaque objet de cette chaîne a la capacité de traiter l'événement ou de le transmettre à l'objet répondeur suivant via la propriété next.
Le mécanisme est basé sur la hiérarchie des vues : lorsqu'un toucher se produit, iOS détermine d'abord quelle vue a été touchée (via le hit-testing) et crée une chaîne commençant par cette vue jusqu'à UIApplication. UIApplication est le dernier maillon de la chaîne — si un événement l'atteint et n'est pas traité, il est simplement ignoré.
Selon Apple, ce modèle est essentiel pour encapsuler la logique de traitement des événements. Un développeur peut redéfinir le comportement d'une vue spécifique sans affecter les autres éléments de la hiérarchie. Par exemple, UITextField devient le premier répondeur lorsqu'il reçoit le focus et reçoit les événements du clavier sans nécessiter de modifications dans le UIViewController parent.
Le traitement des événements via la Responder Chain se déroule en deux étapes : d'abord, iOS détermine quelle vue a reçu l'événement (hit-testing), puis il exécute la chaîne de répondeurs pour le traiter. Si un objet n'implémente pas la méthode correspondante, l'événement est transmis plus loin.
La chaîne est formée dynamiquement en fonction du premier répondeur actuel et de la hiérarchie des vues. L'ordre standard est : premier répondeur → sa vue → superview → UIViewController → vue racine → UIWindow → UIApplication. Si l'un de ces objets implémente, par exemple, touchesBegan, l'événement est traité à ce niveau et n'est pas transmis plus loin.
import UIKit
class CustomView: UIView {
override func touchesBegan(
_ touches: Set<UITouch>,
with event: UIEvent?
) {
// Contact traité à ce niveau de vue
print("CustomView a traité le contact")
// Transmettre l'événement le long de la chaîne
super.touchesBegan(touches, with: event)
}
}
Une caractéristique clé est que l'appel à super.touchesBegan n'est pas obligatoire. S'il n'est pas appelé, l'événement sera traité uniquement au niveau actuel et ne continuera pas le long de la Responder Chain. Cela donne au développeur un contrôle total sur les objets qui participent au traitement.
Lorsqu'un objet reçoit un événement mais ne le traite pas (ne redéfinit pas la méthode), iOS transmet automatiquement l'événement à l'objet répondeur suivant via la propriété next. Cette propriété forme une liste chaînée simple, appelée Responder Chain.
UIViewController se situe entre sa vue et UIWindow : si la vue ne traite pas l'événement, le contrôleur a la possibilité de le faire. Ceci est particulièrement utile pour la logique commune — par exemple, le traitement d'un geste qui doit fonctionner sur toute la scène, quelle que soit la vue sous le doigt de l'utilisateur.
Hit-Testing est le processus par lequel iOS détermine quelle vue se trouve sous le point de contact. La méthode hitTest:withEvent: parcourt la hiérarchie des vues à partir de UIWindow vers le bas, en vérifiant quelle vue enfant contient le point de contact et n'est pas masquée.
L'algorithme fonctionne de manière récursive : pour chaque niveau, iOS vérifie les vues dans l'ordre inverse d'ajout (d'abord les plus hautes). Si une vue n'est pas masquée, n'est pas transparente et que le point se trouve dans ses limites, hitTest est exécuté récursivement pour toutes ses sous-vues. La vue la plus profonde satisfaisant toutes les conditions devient la vue hit-test — le premier objet dans la Responder Chain.
override func hitTest(
_ point: CGPoint,
with event: UIEvent?
) -> UIView? {
if isUserInteractionEnabled &&
isHidden == false &&
alpha > 0.01 &&
point(inside: point, with: event) {
return super.hitTest(point, with: event)
}
return nil
}
Les développeurs peuvent redéfinir hitTest pour modifier le comportement par défaut. Par exemple, pour étendre la zone de contact d'un petit bouton ou rediriger l'événement vers une autre vue qui n'est pas physiquement sous le doigt. C'est un outil puissant pour créer des éléments interactifs personnalisés.
UIResponder est la classe de base pour tous les objets qui peuvent traiter des événements dans iOS. UIView, UIViewController, UIApplication et UIWindow héritent de UIResponder. La classe fournit un ensemble de méthodes qui peuvent être redéfinies pour traiter différents types d'événements.
Les principaux groupes de méthodes incluent touchesBegan, touchesMoved, touchesEnded, touchesCancelled pour les touches ; pressesBegan, pressesEnded pour les boutons physiques ; et motionBegan, motionEnded pour les événements de l'accéléromètre. Chaque méthode reçoit un ensemble d'objets UITouch ou UIPress et une référence à UIEvent contenant des métadonnées supplémentaires sur l'événement.
| Méthode UIResponder | Fonction |
|---|---|
| touchesBegan | Appelée au début d'un contact |
| touchesMoved | Appelée lors du déplacement du doigt |
| touchesEnded | Appelée lors du retrait du doigt |
| touchesCancelled | Appelée en cas d'interruption (appel, balayage du centre de contrôle) |
| pressesBegan | Appelée lors de l'appui sur un bouton physique |
Il est important de comprendre qu'iOS appelle ces méthodes uniquement pour le premier répondeur et les objets suivants dans la chaîne. Si aucun objet n'a redéfini la méthode, l'événement ne génère pas d'erreur — il est simplement ignoré. Pour déboguer le traitement des événements, utilisez un point d'arrêt symbolique sur UIResponder touchEvent.
Les composants UIKit standard utilisent activement la Responder Chain pour leur fonctionnement. UITextField devient le premier répondeur lorsqu'il reçoit le focus, ce qui ouvre automatiquement le clavier. UIButton traite les touches via le mécanisme UIControl, qui repose également sur la chaîne de répondeurs.
UITableView et UICollectionView utilisent la chaîne de répondeurs pour traiter la sélection de cellules et les gestes de défilement. Si un utilisateur touche une cellule, l'événement atteint d'abord la cellule elle-même, puis UITableView, et seulement ensuite UIViewController. UIGestureRecognizer a une priorité plus élevée que touchesBegan — si un reconnaisseur de gestes est ajouté à une vue, il recevra l'événement en premier.
Selon Apple, l'utilisation correcte de la Responder Chain est essentielle pour l'accessibilité de l'application. VoiceOver et d'autres technologies d'assistance utilisent la chaîne de répondeurs pour naviguer entre les éléments de l'interface. Si la chaîne est rompue, les utilisateurs handicapés ne pourront pas interagir avec l'application.
UIMenuController pour l'affichage des menus contextuels utilise également la Responder Chain. Lorsqu'un utilisateur invoque le menu, le système recherche un premier répondeur qui implémente les méthodes canPerformAction et les méthodes d'action correspondantes. Le menu s'affiche uniquement pour les actions que le répondeur actuel prend en charge.
Cela permet, par exemple, d'afficher les commandes Couper, Copier, Coller uniquement lorsque UITextField est focus, et de les masquer lors du travail avec UILabel. Un développeur peut ajouter des actions personnalisées au menu contextuel en les implémentant dans une sous-classe de UIResponder et en retournant true depuis canPerformAction.
Créer un objet répondeur personnalisé donne au développeur un contrôle total sur le traitement des événements. Pour ce faire, vous devez créer une sous-classe de UIResponder (ou UIView/UIViewController) et redéfinir les méthodes de traitement des événements nécessaires.
Les objets répondeurs personnalisés sont souvent utilisés pour traiter des gestes spécifiques qui ne sont pas couverts par UIGestureRecognizer standard. Par exemple, la reconnaissance de dessin de formes, de combinaisons multi-touch complexes ou de schémas de saisie propriétaires. Un répondeur personnalisé peut agréger les événements de plusieurs doigts et prendre des décisions en fonction de leur combinaison.
class DrawingResponder: UIResponder {
private var activeTouches: [UITouch: CGPoint] = [:]
override func touchesBegan(
_ touches: Set<UITouch>,
with event: UIEvent?
) {
for touch in touches {
activeTouches[touch] = touch.location(in: self)
}
}
override func touchesMoved(
_ touches: Set<UITouch>,
with event: UIEvent?
) {
for touch in touches {
let currentPoint = touch.location(in: self)
activeTouches[touch] = currentPoint
drawLine(from: activeTouches[touch]!, to: currentPoint)
}
}
}
Lors de la création d'un répondeur personnalisé, il est important de configurer correctement la chaîne next. Si votre objet ne fait pas partie de la hiérarchie standard d'UIKit, vous devez spécifier explicitement quel objet sera son next responder. Cela garantit que les événements non traités continuent de se déplacer le long de la Responder Chain.
Foire aux questions
Responder Chain est une chaîne hiérarchique d'objets UIResponder à travers laquelle iOS transmet séquentiellement les événements tactiles, les pressions et les gestes. Si un objet ne traite pas l'événement, il est transmis à l'objet répondeur suivant dans la chaîne jusqu'à UIApplication.
Vous pouvez modifier l'ordre en redéfinissant la propriété next de votre objet UIResponder. En retournant un objet différent au lieu de l'objet par défaut, vous redirigez les événements non traités vers celui-ci. Cela est utile pour les hiérarchies non standard, par exemple lorsqu'un conteneur personnalisé gère plusieurs contrôleurs enfants.
Hit-Testing détermine quelle vue se trouve sous le point de contact (le destinataire initial), tandis que Responder Chain détermine comment l'événement est transmis entre les objets après le hit-test. Hit-test trouve le premier objet, la responder chain assure le routage supplémentaire si cet objet ne traite pas l'événement.
Pour interrompre la chaîne, traitez simplement l'événement dans votre UIResponder et n'appelez pas super. Par exemple, en redéfinissant touchesBegan et en n'appelant pas super.touchesBegan, vous empêchez la transmission de l'événement plus loin. L'événement sera traité au niveau actuel et n'atteindra pas les maillons suivants de la chaîne.
Les raisons les plus courantes : isUserInteractionEnabled est défini sur false, la vue est masquée (isHidden = true), alpha est inférieur à 0,01, ou la vue se trouve en dehors des limites du conteneur parent. Vérifiez également qu'il n'y a pas de UIGestureRecognizer sur la vue ou sa superview qui intercepte les événements avant touchesBegan.
Résumé
Nous développerons une application mobile clé en main
IT Sectr crée des applications iOS et Android pour les startups et les entreprises depuis 2017. Nous vous conseillerons et vous proposerons la meilleure solution.
Lisez aussi