Gesture Recognizer — co to je, zpracování dotyků v iOS

Autor: IT Sectr Publikováno: 2026-02-27 Doba čtení: 8 min
Gesture Recognizer — abstrakce v UIKit, která převádí sekvenci dotyků uživatele na rozpoznané gesto: tap, přejetí, dlouhé stisknutí, sevření nebo otočení. Místo ručního sledování souřadnic v metodách touchesBegan/touchesMoved vývojář přidá hotový objekt UIGestureRecognizer na UIView a implementuje metodu akce. Podle Apple Developer Documentation podporuje UIGestureRecognizer 7 vestavěných podtříd, které pokrývají 95% typických gest v mobilních aplikacích.

Hlavní body

  • UIGestureRecognizer — abstraktní třída UIKit pro rozpoznávání vzorů dotyků: tapů, přejetí, sevření, otočení a dlouhých stisknutí.
  • 7 vestavěných podtříd: UITapGestureRecognizer, UISwipeGestureRecognizer, UIPinchGestureRecognizer, UIRotationGestureRecognizer, UILongPressGestureRecognizer, UIPanGestureRecognizer, UIScreenEdgePanGestureRecognizer.
  • Každý rozpoznávač má stav (possible, began, changed, ended, cancelled, failed), který se aktualizuje s pohybem prstů.
  • Pro řešení konfliktů mezi gesty se používá metoda require(toFail:), která nastavuje prioritu rozpoznávání.
  • Gesture Recognizer pracuje s UIKit a UIViewRepresentable ve SwiftUI, ale v nativním SwiftUI se používají modifikátory gest.

Co je Gesture Recognizer?

UIGestureRecognizer — abstraktní základní třída v UIKit, která rozkládá proces rozpoznávání gest na samostatné objekty. Každá podtřída je zodpovědná za jeden typ gesta: UITapGestureRecognizer — za tap určitým počtem prstů, UISwipeGestureRecognizer — za přejetí v daném směru. Vývojář přidá rozpoznávač na UIView pomocí metody addGestureRecognizer(:) a UIKit automaticky sleduje dotyky, aktualizuje stav a volá akci při rozpoznání.

Před příchodem UIGestureRecognizer (iOS 3.2, 2010) vývojáři přepisovali metody UIResponder — touchesBegan, touchesMoved, touchesEnded — a ručně analyzovali trajektorii dotyků. To vedlo k duplicitě kódu a chybám při zpracování současných dotyků. Apple tuto logiku zapouzdřil do UIGestureRecognizer a přidal podporu pro multitouch, rušení gest a současnou práci více rozpoznávačů na jednom zobrazení.

Podle relací WWDC zpracovává Gesture Recognizer až 11 současných dotyků na iPadu a 5 na iPhonu. V IT Sectr používáme UIGestureRecognizer jako standardní způsob zpracování vstupu uživatele ve všech UIKit projektech — to eliminovalo chyby spojené s ručním sledováním touchesBegan.

Stavy UIGestureRecognizer

Každý UIGestureRecognizer prochází 7 možnými stavy, definovanými ve enumu UIGestureRecognizer.State. Tyto stavy odrážejí životní cyklus rozpoznávání: od detekce dotyku po dokončení nebo zrušení gesta. Pochopení stavů je kritické pro implementaci vlastních rozpoznávačů a ladění konfliktů.

Stav Význam Kdy vzniká
.possible Počáteční stav, gesto ještě nebylo rozpoznáno Ihned po přidání do zobrazení
.began Gesto bylo rozpoznáno a začalo se provádět Při prvním pohybu prstu pro pan/longPress
.changed Parametry gesta se změnily (souřadnice, úhel) Při každém pohybu prstu
.ended Uživatel zvedl prst, gesto bylo dokončeno Při touchesEnded
.cancelled Gesto bylo přerušeno systémem (příchozí hovor, změna orientace) Při touchesCancelled
.failed Gesto nebylo rozpoznáno podle podmínek Při touchesCancelled bez rozpoznání
.recognized Synonymum pro .ended; gesto bylo úspěšně rozpoznáno Stejné jako .ended

Diskrétní gesta (tap, swipe) přecházejí z .possible přímo do .ended nebo .failed. Spojitá gesta (pan, pinch, rotation, longPress) procházejí .possible → .began → .changed (vícekrát) → .ended. V metodě akce kontrolujte gestureRecognizer.state — to umožňuje rozlišit začátek, změnu a konec gesta.

Typy gest v iOS

UIKit poskytuje 7 vestavěných podtříd UIGestureRecognizer, které pokrývají většinu scénářů interakce. Každá podtřída má specifická nastavení: numberOfTapsRequired pro tap, direction pro přejetí, minimumPressDuration pro dlouhé stisknutí.

  • UITapGestureRecognizer — rozpoznává jednotlivé a vícenásobné tapy. Nastavuje se počet dotyků (numberOfTapsRequired) a prstů (numberOfTouchesRequired). Používá se pro tlačítka, odkazy, výběr prvků.
  • UISwipeGestureRecognizer — rozpoznává přejetí v jednom ze čtyř směrů (right, left, up, down). Vlastnost direction nastavuje směr; numberOfTouchesRequired — počet prstů.
  • UIPanGestureRecognizer — spojité gesto pro přetahování. Metoda translation(in:) vrací posun od počátečního bodu. Používá se pro drag-and-drop, kolotoče, pull-to-refresh.
  • UIPinchGestureRecognizer — škálování dvěma prsty. Vlastnost scale odráží aktuální faktor měřítka. Podrobně rozebrán v článku Pinch-to-Zoom.
  • UIRotationGestureRecognizer — otáčení dvěma prsty. Vlastnost rotation ukládá úhel v radiánech. Používá se pro otáčení obrázků, map, pláten.
  • UILongPressGestureRecognizer — dlouhé stisknutí. Parametry minimumPressDuration (sekundy), allowableMovement (pixely). Používá se pro kontextové nabídky, přetahování prvků.
  • UIScreenEdgePanGestureRecognizer — panorámování od okraje obrazovky. Vlastnost edges určuje, který okraj sledovat. Používá se pro navigační gesta, oznamovací závěsy.

Pro vlastní gesta (např. kreslení cikcaku) se vytvoří podtřída UIGestureRecognizer s přepsáním metod touchesBegan, touchesMoved, touchesEnded a aktualizací stavu. Apple doporučuje používat vestavěné třídy, kde je to možné — jsou optimalizované a správně spolu interagují.

Řešení konfliktů mezi gesty

Když se na jednom UIView používá několik UIGestureRecognizer (např. tap a double-tap), vzniká konflikt rozpoznávání: při dvojitém tapu se nejprve aktivuje jednotlivý tap. K řešení Apple poskytuje metodu require(toFail:), která zpožďuje rozpoznání jednoho gesta, dokud druhé neskončí neúspěchem.

Mechanismus funguje následovně: voláním tapRecognizer.require(toFail: doubleTapRecognizer) určíte, že tapRecogniser přejde do stavu .recognized až poté, co doubleTapRecogniser skončí v .failed. To přidá zpoždění ~0,3 sekundy před provedením jednotlivého tapu — uživatel klepne dvakrát a první tap je ignorován. Alternativní metodou je delegát UIGestureRecognizerDelegate s metodou gestureRecognizer(_:shouldRecognizeSimultaneouslyWith:), která povoluje současné rozpoznávání (např. pan + pinch pro mapu).

Podle WWDC 2020 souvisí přibližně 15% chyb v UIKit aplikacích s nesprávnou konfigurací konfliktů gest. V IT Sectr jsme standardizovali přístup: pro každou obrazovku se vytvoří schéma gest s prioritami require(toFail:) — to zcela eliminovalo chyby s dvojitým spouštěním tapů.

Příklady kódu ve Swift

Příklad 1: UITapGestureRecognizer — tap na obrázek

Přidá obsluhu jednotlivého tapu na UIImageView. Při tapu obrázek změní průhlednost — nejjednodušší příklad ukazující připojení gesta k zobrazení.

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

Klíčový bod: isUserInteractionEnabled na UIImageView je ve výchozím nastavení false — bez tohoto příznaku Gesture Recognizer nebude přijímat dotyky. Pro UIView a UIButton je příznak ve výchozím nastavení zapnutý. Metoda akce přijímá parametr UITapGestureRecognizer, přes který lze získat location(in:) pro určení souřadnic tapu.

Příklad 2: UISwipeGestureRecognizer — přejetí pro navigaci

Implementuje přejetí doleva pro návrat na předchozí obrazovku. Demonstruje nastavení směru a připojení gesta k kořenovému zobrazení kontroleru.

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 — diskrétní gesto: přechází do .recognised ihned po rozpoznání, bez mezilehlého .changed. Proto v akci není třeba kontrolovat stav — gesto je buď rozpoznáno (akce je volána), nebo není. Vlastnost direction přijímá jednu ze čtyř hodnot: .left, .right, .up, .down. Pro podporu více směrů vytvořte samostatné rozpoznávače pro každý směr.

Příklad 3: Kombinace gest s require(toFail:)

Ukazuje, jak nakonfigurovat jednotlivý a dvojitý tap na stejném zobrazení bez konfliktu. Rozpoznávač dvojitého tapu má prioritu — jednotlivý tap se aktivuje pouze pokud dvojitý tap nebyl rozpoznán.

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

Bez require(toFail:) se při dvojitém tapu nejprve zavolá handleSingleTap, poté handleDoubleTap — to kazí UX. S require(toFail:) jednotlivý tap čeká ~0,3 sekundy, aby se ujistil, že druhý tap nebude následovat. V IT Sectr se tento vzor používá v editorech obrázků a galeriích, kde dvojitý tap přibližuje a jednotlivý tap vybírá prvek.

Často kladené otázky

Lze použít více Gesture Recognizer na jednom zobrazení?

Ano, UIView podporuje více UIGestureRecognizer současně. Pro řešení konfliktů použijte metodu require(toFail:), která nastavuje pořadí rozpoznávání. Pro paralelní práci gest (např. pan + pinch na mapě) implementujte delegáta gestureRecognizer(_:shouldRecognizeSimultaneouslyWith:), který vrací true.

Čím se UIGestureRecognizer liší od touchesBegan?

UIGestureRecognizer — vysokourovňová abstrakce, která automaticky rozpoznává vzory dotyků a spravuje stavy. touchesBegan — nízkourovňová metoda UIResponder vyžadující ruční sledování souřadnic, časování a rušení dotyků. Gesture Recognizer je jednodušší, spolehlivější a upřednostňuje se pro standardní gesta; touchesBegan je ospravedlnitelný pouze pro vlastní grafiku.

Funguje Gesture Recognizer ve SwiftUI?

V nativním SwiftUI se používají modifikátory: onTapGesture, onLongPressGesture, DragGesture, MagnificationGesture, RotationGesture. To jsou deklarativní protějšky UIGestureRecognizer integrované do hierarchie SwiftUI. V případě potřeby lze UIKit rozpoznávač zabalit přes UIViewRepresentable, ale Apple doporučuje používat nativní SwiftUI gesta.

Shrnutí

  • UIGestureRecognizer — UIKit abstrakce pro rozklad logiky rozpoznávání gest na samostatné objekty s automatickou správou stavů.
  • 7 vestavěných podtříd pokrývá 95% typických gest: tap, přejetí, panorámování, sevření, otočení, dlouhé stisknutí a přejetí od okraje.
  • Každý rozpoznávač prochází 7 stavy — od .possible do .ended/.failed, což umožňuje přesné sledování diskrétních a spojitých gest.
  • Metoda require(toFail:) řeší konflikty mezi gesty na stejném zobrazení nastavením priority rozpoznávání.
  • Ve SwiftUI se používají deklarativní modifikátory gest, ale UIKit rozpoznávače jsou dostupné přes UIViewRepresentable.
  • Gesture Recognizer je povinný pro UIKit projekty; touchesBegan je ospravedlnitelný pouze pro vlastní kreslení a nízkourovňovou grafiku.
  • Používejte require(toFail:) pro páry tap/double-tap a gestureRecognizer(_:shouldRecognizeSimultaneouslyWith:) pro paralelní gesta.

Vyvineme mobilní aplikaci na klíč

IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.

Prodiskutovat projekt

Přečtěte si také