Gesture Recognizer — qu'est-ce que c'est, gestion des touches en iOS

Auteur : IT Sectr Publié le : 2026-02-27 Temps de lecture : 8 min
Gesture Recognizer est une abstraction dans UIKit qui convertit une séquence de touches utilisateur en un geste reconnu : tap, swipe, pression longue, pincement ou rotation. Au lieu de suivre manuellement les coordonnées dans les méthodes touchesBegan/touchesMoved, le développeur ajoute un objet UIGestureRecognizer prêt à l'emploi à UIView et implémente une méthode d'action. Selon la Documentation Développeur Apple, UIGestureRecognizer prend en charge 7 sous-classes intégrées couvrant 95% des gestes typiques dans les applications mobiles.

Points clés

  • UIGestureRecognizer est une classe abstraite UIKit pour reconnaître les motifs de toucher : taps, swipes, pincements, rotations et pressions longues.
  • 7 sous-classes intégrées : UITapGestureRecognizer, UISwipeGestureRecognizer, UIPinchGestureRecognizer, UIRotationGestureRecognizer, UILongPressGestureRecognizer, UIPanGestureRecognizer, UIScreenEdgePanGestureRecognizer.
  • Chaque reconnaisseur a un état (possible, began, changed, ended, cancelled, failed) qui se met à jour au fur et à mesure que les doigts bougent.
  • Pour résoudre les conflits entre gestes, on utilise la méthode require(toFail:) pour définir la priorité de reconnaissance.
  • Gesture Recognizer fonctionne avec UIKit et UIViewRepresentable dans SwiftUI, mais SwiftUI natif utilise des modificateurs de gestes.

Qu'est-ce que Gesture Recognizer ?

UIGestureRecognizer est une classe de base abstraite dans UIKit qui décompose le processus de reconnaissance des gestes en objets séparés. Chaque sous-classe gère un type de geste : UITapGestureRecognizer gère un tap avec un nombre spécifique de touches, UISwipeGestureRecognizer gère un swipe dans une direction donnée. Le développeur ajoute le reconnaisseur à UIView via la méthode addGestureRecognizer(:), et UIKit suit automatiquement les touches, met à jour l'état et appelle une action lors de la reconnaissance.

Avant UIGestureRecognizer (iOS 3.2, 2010), les développeurs redéfinissaient les méthodes UIResponder — touchesBegan, touchesMoved, touchesEnded — et analysaient manuellement les trajectoires des touches. Cela entraînait une duplication de code et des erreurs lors du traitement des touches simultanées. Apple a encapsulé cette logique dans UIGestureRecognizer, ajoutant la prise en charge du multitouch, de l'annulation des gestes et du fonctionnement simultané de plusieurs reconnaisseurs sur une même vue.

Selon les sessions WWDC, Gesture Recognizer gère jusqu'à 11 touches simultanées sur iPad et 5 sur iPhone. Chez IT Sectr, nous utilisons UIGestureRecognizer comme méthode standard de gestion des entrées utilisateur dans tous les projets UIKit — cela a éliminé les bugs associés au suivi manuel de touchesBegan.

États de UIGestureRecognizer

Chaque UIGestureRecognizer passe par 7 états possibles, définis dans l'énumération UIGestureRecognizer.State. Ces états reflètent le cycle de vie de la reconnaissance : de la détection de la touche à l'achèvement ou à l'annulation. Comprendre les états est essentiel pour implémenter des reconnaisseurs personnalisés et déboguer les conflits.

État Signification Quand il se produit
.possible État initial, geste pas encore reconnu Immédiatement après l'ajout à une vue
.began Geste reconnu et commencé à s'exécuter Au premier mouvement du doigt pour pan/longPress
.changed Paramètres du geste modifiés (coordonnées, angle) À chaque mouvement du doigt
.ended L'utilisateur a levé le doigt, geste terminé À touchesEnded
.cancelled Geste interrompu par le système (appel entrant, changement d'orientation) À touchesCancelled
.failed Geste non reconnu selon les conditions À touchesCancelled sans reconnaissance
.recognized Synonyme de .ended ; geste reconnu avec succès Identique à .ended

Les gestes discrets (tap, swipe) passent de .possible directement à .ended ou .failed. Les gestes continus (pan, pinch, rotation, longPress) parcourent .possible → .began → .changed (répété) → .ended. Dans la méthode d'action, vérifiez gestureRecognizer.state — cela permet de distinguer le début, le changement et la fin d'un geste.

Types de gestes dans iOS

UIKit fournit 7 sous-classes intégrées de UIGestureRecognizer, couvrant la plupart des scénarios d'interaction. Chaque sous-classe a des paramètres spécifiques : numberOfTapsRequired pour le tap, direction pour le swipe, minimumPressDuration pour la pression longue.

  • UITapGestureRecognizer — reconnaît les taps simples et multiples. Nombre de taps (numberOfTapsRequired) et de doigts (numberOfTouchesRequired) configurable. Utilisé pour les boutons, liens, sélection d'éléments.
  • UISwipeGestureRecognizer — reconnaît un swipe dans l'une des quatre directions (right, left, up, down). La propriété direction définit la direction ; numberOfTouchesRequired définit le nombre de doigts.
  • UIPanGestureRecognizer — geste continu pour faire glisser. La méthode translation(in:) retourne le déplacement depuis le point initial. Utilisé pour le glisser-déposer, les carrousels, le pull-to-refresh.
  • UIPinchGestureRecognizer — zoom à deux doigts. La propriété scale reflète le facteur d'échelle actuel. Détaillé dans l'article Pinch-to-Zoom.
  • UIRotationGestureRecognizer — rotation à deux doigts. La propriété rotation stocke l'angle en radians. Utilisé pour faire pivoter des images, cartes, toiles.
  • UILongPressGestureRecognizer — pression longue. Paramètres : minimumPressDuration (secondes), allowableMovement (pixels). Utilisé pour les menus contextuels, le glissement d'éléments.
  • UIScreenEdgePanGestureRecognizer — glissement depuis le bord de l'écran. La propriété edges spécifie quel bord suivre. Utilisé pour les gestes de navigation, les panneaux de notification.

Pour les gestes personnalisés (par exemple, dessiner un zigzag), créez une sous-classe de UIGestureRecognizer en redéfinissant touchesBegan, touchesMoved, touchesEnded et en mettant à jour l'état. Apple recommande d'utiliser les classes intégrées lorsque c'est possible — elles sont optimisées et interagissent correctement entre elles.

Résolution de conflits entre gestes

Lorsque plusieurs UIGestureRecognizer sont utilisés sur une même UIView (par exemple, tap et double tap), un conflit de reconnaissance se produit : lors d'un double tap, le tap simple se déclenche en premier. Apple fournit la méthode require(toFail:) pour retarder la reconnaissance d'un geste jusqu'à ce qu'un autre échoue.

Le mécanisme fonctionne ainsi : en appelant tapRecognizer.require(toFail: doubleTapRecognizer), vous spécifiez que tapRecognizer passera à l'état .recognized seulement après que doubleTapRecognizer se termine en .failed. Cela ajoute un délai d'environ 0,3 seconde avant l'exécution du tap simple — l'utilisateur tape deux fois et le premier tap est ignoré. Une approche alternative est le délégué UIGestureRecognizerDelegate avec la méthode gestureRecognizer(_:shouldRecognizeSimultaneouslyWith:), qui permet la reconnaissance simultanée (par exemple, pan + pinch pour une carte).

Selon la WWDC 2020, environ 15% des bugs dans les applications UIKit sont liés à une configuration incorrecte des conflits de gestes. Chez IT Sectr, nous avons standardisé l'approche : chaque écran a un schéma de gestes avec des priorités require(toFail:) — cela a complètement éliminé les bugs de double déclenchement des taps.

Exemples de code en Swift

Exemple 1 : UITapGestureRecognizer — Tap sur image

Ajoute un gestionnaire de tap simple à UIImageView. Au tap, l'opacité de l'image change — un exemple simple montrant la liaison d'un geste à une vue.

swift
import UIKit

class ImageViewController: UIViewController {

    @IBOutlet private var imageView: UIImageView!

    override func viewDidLoad() {
        super.viewDidLoad()
        let tap = UITapGestureRecognizer(
            target: self,
            action: #selector(handleTap(_:))
        )
        tap.numberOfTapsRequired = 1
        imageView.addGestureRecognizer(tap)
        imageView.isUserInteractionEnabled = true
    }

    @objc private func handleTap(_: UITapGestureRecognizer) {
        UIView.animate(withDuration: 0.2) {
            self.imageView.alpha = self.imageView.alpha == 1.0 ? 0.5 : 1.0
        }
    }
}

Point clé : isUserInteractionEnabled sur UIImageView est false par défaut — sans ce drapeau, Gesture Recognizer ne recevra pas les touches. Pour UIView et UIButton, ce drapeau est activé par défaut. La méthode d'action accepte un paramètre UITapGestureRecognizer, via lequel on peut obtenir location(in:) pour déterminer les coordonnées du tap.

Exemple 2 : UISwipeGestureRecognizer — Balayer pour naviguer

Implémente un balayage vers la gauche pour revenir à l'écran précédent. Montre la configuration de direction et la liaison du geste à la vue racine du contrôleur.

swift
import UIKit

class DetailViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        let swipeLeft = UISwipeGestureRecognizer(
            target: self,
            action: #selector(handleSwipe(_:))
        )
        swipeLeft.direction = .left
        view.addGestureRecognizer(swipeLeft)
    }

    @objc private func handleSwipe(_: UISwipeGestureRecognizer) {
        navigationController?.popViewController(animated: true)
    }
}

UISwipeGestureRecognizer est un geste discret : il passe à .recognized immédiatement après la reconnaissance, sans états .changed intermédiaires. Par conséquent, il n'est pas nécessaire de vérifier l'état dans l'action — le geste est soit reconnu (l'action se déclenche), soit non. La propriété direction accepte l'une des quatre valeurs : .left, .right, .up, .down. Pour prendre en charge plusieurs directions, créez des reconnaisseurs séparés pour chacune.

Exemple 3 : Combinaison de gestes avec require(toFail:)

Montre comment configurer le tap simple et double sur une même vue sans conflit. Le reconnaisseur de double tap a la priorité — le tap simple se déclenche seulement si le double tap n'est pas reconnu.

swift
import UIKit

class TapViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        let singleTap = UITapGestureRecognizer(
            target: self,
            action: #selector(handleSingleTap)
        )
        singleTap.numberOfTapsRequired = 1

        let doubleTap = UITapGestureRecognizer(
            target: self,
            action: #selector(handleDoubleTap)
        )
        doubleTap.numberOfTapsRequired = 2

        singleTap.require(toFail: doubleTap)

        view.addGestureRecognizer(singleTap)
        view.addGestureRecognizer(doubleTap)
    }

    @objc private func handleSingleTap() {
        print("Single tap — after 0.3s delay")
    }

    @objc private func handleDoubleTap() {
        print("Double tap — instant")
    }
}

Sans require(toFail:), lors d'un double tap, handleSingleTap se déclenche en premier, puis handleDoubleTap — cela brise l'UX. Avec require(toFail:), le tap simple attend environ 0,3 seconde pour s'assurer qu'un second tap ne suit pas. Chez IT Sectr, ce modèle est utilisé dans les éditeurs d'images et les galeries, où un double tap zoome et un tap simple sélectionne un élément.

Questions fréquentes

Peut-on utiliser plusieurs Gesture Recognizers sur une même vue ?

Oui, UIView prend en charge plusieurs instances de UIGestureRecognizer simultanément. Pour résoudre les conflits, utilisez la méthode require(toFail:) qui définit l'ordre de reconnaissance. Pour le fonctionnement parallèle des gestes (par exemple, pan + pinch sur une carte), implémentez la méthode déléguée gestureRecognizer(_:shouldRecognizeSimultaneouslyWith:) retournant true.

En quoi UIGestureRecognizer diffère-t-il de touchesBegan ?

UIGestureRecognizer est une abstraction de haut niveau qui reconnaît automatiquement les motifs de toucher et gère les états. touchesBegan est une méthode de bas niveau de UIResponder qui nécessite un suivi manuel des coordonnées, un minutage et une annulation des touches. Gesture Recognizer est plus simple, plus fiable et préférable pour les gestes standard ; touchesBegan n'est justifié que pour les graphismes personnalisés.

Gesture Recognizer fonctionne-t-il dans SwiftUI ?

SwiftUI natif utilise des modificateurs : onTapGesture, onLongPressGesture, DragGesture, MagnificationGesture, RotationGesture. Ce sont des analogues déclaratifs de UIGestureRecognizer intégrés dans la hiérarchie SwiftUI. Si nécessaire, on peut envelopper un reconnaisseur UIKit via UIViewRepresentable, mais Apple recommande d'utiliser les gestes natifs de SwiftUI.

Résumé

  • UIGestureRecognizer est une abstraction UIKit pour décomposer la logique de reconnaissance des gestes en objets séparés avec gestion automatique des états.
  • 7 sous-classes intégrées couvrent 95% des gestes typiques : tap, swipe, pan, pinch, rotation, long press et edge swipe.
  • Chaque reconnaisseur passe par 7 états — de .possible à .ended/.failed, permettant un suivi précis des gestes discrets et continus.
  • La méthode require(toFail:) résout les conflits entre gestes sur une même vue en définissant la priorité de reconnaissance.
  • SwiftUI utilise des modificateurs de gestes déclaratifs, mais les reconnaisseurs UIKit sont disponibles via UIViewRepresentable.
  • Gesture Recognizer est obligatoire pour les projets UIKit ; touchesBegan n'est justifié que pour le dessin personnalisé et les graphismes bas niveau.
  • Utilisez require(toFail:) pour les paires tap/double tap et gestureRecognizer(_:shouldRecognizeSimultaneouslyWith:) pour les gestes parallèles.

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.

Discuter du projet

Lisez aussi