Gesture Recognizer — wat is het, aanrakingen verwerken in iOS

Auteur: IT Sectr Gepubliceerd: 2026-02-27 Leestijd: 8 min
Gesture Recognizer — een abstractie in UIKit die een reeks aanrakingen van de gebruiker omzet in een herkend gebaar: tap, swipe, lang indrukken, knijpen of draaien. In plaats van handmatig coördinaten bijhouden in touchesBegan/touchesMoved-methoden, voegt de ontwikkelaar een kant-en-klaar UIGestureRecognizer-object toe aan UIView en implementeert een action-methode. Volgens Apple Developer Documentation ondersteunt UIGestureRecognizer 7 ingebouwde subklassen die 95% van de typische gebaren in mobiele apps dekken.

Belangrijkste punten

  • UIGestureRecognizer — abstracte UIKit-klasse voor het herkennen van aanraakpatronen: taps, swipes, knijpen, draaien en lang indrukken.
  • 7 ingebouwde subklassen: UITapGestureRecognizer, UISwipeGestureRecognizer, UIPinchGestureRecognizer, UIRotationGestureRecognizer, UILongPressGestureRecognizer, UIPanGestureRecognizer, UIScreenEdgePanGestureRecognizer.
  • Elke herkenner heeft een status (possible, began, changed, ended, cancelled, failed) die wordt bijgewerkt terwijl de vingers bewegen.
  • Voor het oplossen van conflicten tussen gebaren wordt de methode require(toFail:) gebruikt, die de herkenningsprioriteit instelt.
  • Gesture Recognizer werkt met UIKit en UIViewRepresentable in SwiftUI, maar in native SwiftUI worden gebaar modifiers toegepast.

Wat is Gesture Recognizer?

UIGestureRecognizer — een abstracte basisklasse in UIKit die het herkenningsproces van gebaren opsplitst in afzonderlijke objecten. Elke subklasse is verantwoordelijk voor één type gebaar: UITapGestureRecognizer — voor tap met een bepaald aantal vingers, UISwipeGestureRecognizer — voor swipe in een bepaalde richting. De ontwikkelaar voegt de herkenner toe aan UIView via de methode addGestureRecognizer(:), en UIKit volgt automatisch aanrakingen, werkt de status bij en roept de actie aan bij herkenning.

Vóór de komst van UIGestureRecognizer (iOS 3.2, 2010) overschreven ontwikkelaars de UIResponder-methoden — touchesBegan, touchesMoved, touchesEnded — en analyseerden ze handmatig het traject van aanrakingen. Dit leidde tot code-duplicatie en fouten bij het verwerken van gelijktijdige aanrakingen. Apple heeft deze logica ingekapseld in UIGestureRecognizer en ondersteuning toegevoegd voor multitouch, het annuleren van gebaren en gelijktijdig werken van meerdere herkenners op één weergave.

Volgens WWDC-sessies verwerkt Gesture Recognizer tot 11 gelijktijdige aanrakingen op iPad en 5 op iPhone. Bij IT Sectr gebruiken we UIGestureRecognizer als standaard manier om gebruikersinvoer te verwerken in alle UIKit-projecten — dit heeft bugs gerelateerd aan handmatig bijhouden van touchesBegan geëlimineerd.

UIGestureRecognizer statussen

Elke UIGestureRecognizer doorloopt 7 mogelijke statussen, gedefinieerd in de enum UIGestureRecognizer.State. Deze statussen weerspiegelen de levenscyclus van herkenning: van het detecteren van aanraking tot het voltooien of annuleren van het gebaar. Inzicht in de statussen is cruciaal voor het implementeren van aangepaste herkenners en het debuggen van conflicten.

Status Betekenis Wanneer ontstaat
.possible Beginstatus, gebaar nog niet herkend Direct na toevoegen aan weergave
.began Gebaar herkend en begonnen met uitvoeren Bij eerste vingerbeweging voor pan/longPress
.changed Parameters van gebaar gewijzigd (coördinaten, hoek) Bij elke vingerbeweging
.ended Gebruiker heeft vinger opgetild, gebaar voltooid Bij touchesEnded
.cancelled Gebaar onderbroken door systeem (inkomende oproep, oriëntatiewijziging) Bij touchesCancelled
.failed Gebaar niet herkend volgens voorwaarden Bij touchesCancelled zonder herkenning
.recognized Synoniem voor .ended; gebaar succesvol herkend Hetzelfde als .ended

Discrete gebaren (tap, swipe) gaan van .possible direct naar .ended of .failed. Continue gebaren (pan, pinch, rotation, longPress) doorlopen .possible → .began → .changed (herhaaldelijk) → .ended. Controleer in de action-methode gestureRecognizer.state — dit maakt het mogelijk onderscheid te maken tussen begin, wijziging en einde van het gebaar.

Soorten gebaren in iOS

UIKit biedt 7 ingebouwde subklassen van UIGestureRecognizer, die de meeste interactiescenario's dekken. Elke subklasse heeft specifieke instellingen: numberOfTapsRequired voor tap, direction voor swipe, minimumPressDuration voor lang indrukken.

  • UITapGestureRecognizer — herkent enkele en meerdere taps. Het aantal aanrakingen (numberOfTapsRequired) en vingers (numberOfTouchesRequired) wordt ingesteld. Gebruikt voor knoppen, links, selectie van elementen.
  • UISwipeGestureRecognizer — herkent swipe in een van vier richtingen (right, left, up, down). Eigenschap direction bepaalt de richting; numberOfTouchesRequired — aantal vingers.
  • UIPanGestureRecognizer — continu gebaar voor slepen. Methode translation(in:) retourneert de verplaatsing vanaf het startpunt. Gebruikt voor drag-and-drop, carrousels, pull-to-refresh.
  • UIPinchGestureRecognizer — schalen met twee vingers. Eigenschap scale weerspiegelt de huidige schaalfactor. Gedetailleerd besproken in het artikel Pinch-to-Zoom.
  • UIRotationGestureRecognizer — draaien met twee vingers. Eigenschap rotation slaat de hoek op in radialen. Gebruikt voor het draaien van afbeeldingen, kaarten, canvassen.
  • UILongPressGestureRecognizer — lang indrukken. Parameters minimumPressDuration (seconden), allowableMovement (pixels). Gebruikt voor contextmenu's, slepen van elementen.
  • UIScreenEdgePanGestureRecognizer — pan van de rand van het scherm. Eigenschap edges bepaalt welke rand wordt gevolgd. Gebruikt voor navigatiegebaren, meldingsgordijnen.

Voor aangepaste gebaren (bijvoorbeeld het tekenen van een zigzag) wordt een subklasse van UIGestureRecognizer gemaakt met overschrijving van de methoden touchesBegan, touchesMoved, touchesEnded en bijwerken van de status. Apple raadt aan waar mogelijk ingebouwde klassen te gebruiken — ze zijn geoptimaliseerd en werken correct met elkaar samen.

Conflicten tussen gebaren oplossen

Wanneer op één UIView meerdere UIGestureRecognizer worden gebruikt (bijv. tap en double-tap), ontstaat er een herkenningsconflict: bij dubbeltap wordt eerst de enkele tap geactiveerd. Voor de oplossing biedt Apple de methode require(toFail:), die de herkenning van het ene gebaar uitstelt totdat het andere mislukt.

Het mechanisme werkt als volgt: door tapRecognizer.require(toFail: doubleTapRecognizer) aan te roepen, geeft u aan dat tapRecogniser pas naar de status .recognized gaat nadat doubleTapRecogniser is geëindigd in .failed. Dit voegt een vertraging van ~0,3 seconden toe vóór uitvoering van de enkele tap — de gebruiker tikt twee keer en de eerste tap wordt genegeerd. Een alternatieve methode — de delegate UIGestureRecognizerDelegate met de methode gestureRecognizer(_:shouldRecognizeSimultaneouslyWith:), die gelijktijdige herkenning toestaat (bijv. pan + pinch voor een kaart).

Volgens WWDC 2020 is ongeveer 15% van de bugs in UIKit-apps gerelateerd aan onjuiste configuratie van gebarenconflicten. Bij IT Sectr hebben we de aanpak gestandaardiseerd: voor elk scherm wordt een gebarenschema gemaakt met require(toFail:)-prioriteiten — dit heeft bugs met dubbel geactiveerde taps volledig geëlimineerd.

Codevoorbeelden in Swift

Voorbeeld 1: UITapGestureRecognizer — tap op afbeelding

Voegt een handler voor enkele tap toe op UIImageView. Bij een tap verandert de afbeelding van doorzichtigheid — het eenvoudigste voorbeeld dat het koppelen van een gebaar aan een weergave laat zien.

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
        }
    }
}

Belangrijk punt: isUserInteractionEnabled op UIImageView is standaard false — zonder deze vlag ontvangt Gesture Recognizer geen aanrakingen. Voor UIView en UIButton is de vlag standaard ingeschakeld. De action-methode accepteert een UITapGestureRecognizer-parameter waarmee location(in:) kan worden verkregen om de coördinaten van de tap te bepalen.

Voorbeeld 2: UISwipeGestureRecognizer — swipe voor navigatie

Implementeert een swipe naar links om terug te keren naar het vorige scherm. Demonstreert het instellen van de richting en het koppelen van het gebaar aan de root-weergave van de controller.

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 — een discreet gebaar: het gaat onmiddellijk na herkenning naar .recognised, zonder tussenliggende .changed. Daarom hoeft in de actie de status niet te worden gecontroleerd — het gebaar wordt ofwel herkend (actie wordt aangeroepen) of niet. De eigenschap direction accepteert een van vier waarden: .left, .right, .up, .down. Maak voor ondersteuning van meerdere richtingen aparte herkenners voor elke richting.

Voorbeeld 3: Combinatie van gebaren met require(toFail:)

Laat zien hoe u enkele en dubbele tap op dezelfde weergave configureert zonder conflict. De herkenner van de dubbele tap heeft prioriteit — de enkele tap wordt alleen geactiveerd als de dubbele tap niet is herkend.

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")
    }
}

Zonder require(toFail:) wordt bij dubbeltap eerst handleSingleTap aangeroepen, daarna handleDoubleTap — dit verpest de UX. Met require(toFail:) wacht de enkele tap ~0,3 seconden om er zeker van te zijn dat de tweede tap niet volgt. Bij IT Sectr wordt dit patroon gebruikt in beeldbewerkers en galerijen, waar dubbeltap inzoomt en enkele tap een element selecteert.

Veelgestelde vragen

Kunnen meerdere Gesture Recognizers op één weergave worden gebruikt?

Ja, UIView ondersteunt meerdere UIGestureRecognizer tegelijkertijd. Gebruik voor het oplossen van conflicten de methode require(toFail:), die de herkenningsvolgorde bepaalt. Voor parallelle werking van gebaren (bijv. pan + pinch op een kaart) implementeert u de delegate gestureRecognizer(_:shouldRecognizeSimultaneouslyWith:), die true retourneert.

Waarin verschilt UIGestureRecognizer van touchesBegan?

UIGestureRecognizer — een abstractie op hoog niveau die aanraakpatronen automatisch herkent en statussen beheert. touchesBegan — een methode op laag niveau van UIResponder die handmatig bijhouden van coördinaten, timing en annuleren van aanrakingen vereist. Gesture Recognizer is eenvoudiger, betrouwbaarder en heeft de voorkeur voor standaard gebaren; touchesBegan is alleen gerechtvaardigd voor aangepaste grafische weergave.

Werkt Gesture Recognizer in SwiftUI?

In native SwiftUI worden modifiers gebruikt: onTapGesture, onLongPressGesture, DragGesture, MagnificationGesture, RotationGesture. Dit zijn declaratieve tegenhangers van UIGestureRecognizer, geïntegreerd in de SwiftUI-hiërarchie. Indien nodig kunt u een UIKit-herkenner inpakken via UIViewRepresentable, maar Apple raadt het gebruik van native SwiftUI-gebaren aan.

Samenvatting

  • UIGestureRecognizer — UIKit-abstractie voor het opsplitsen van gebaarherkenningslogica in afzonderlijke objecten met automatisch statusbeheer.
  • 7 ingebouwde subklassen dekken 95% van de typische gebaren: tap, swipe, pan, knijpen, draaien, lang indrukken en swipe vanaf de rand.
  • Elke herkenner doorloopt 7 statussen — van .possible tot .ended/.failed, wat nauwkeurig volgen van discrete en continue gebaren mogelijk maakt.
  • De methode require(toFail:) lost conflicten tussen gebaren op dezelfde weergave op door de herkenningsprioriteit in te stellen.
  • In SwiftUI worden declaratieve gebaar-modifiers gebruikt, maar UIKit-herkenners zijn toegankelijk via UIViewRepresentable.
  • Gesture Recognizer is verplicht voor UIKit-projecten; touchesBegan is alleen gerechtvaardigd voor aangepast tekenen en grafische weergave op laag niveau.
  • Gebruik require(toFail:) voor tap/double-tap-paren en gestureRecognizer(_:shouldRecognizeSimultaneouslyWith:) voor parallelle gebaren.

We ontwikkelen een mobiele applicatie turnkey

IT Sectr creëert sinds 2017 iOS- en Android-applicaties voor startups en bedrijven. We adviseren u en stellen de beste oplossing voor.

Bespreek het project

Lees ook