Gesture Recognizer — vad är det, hantering av beröringar i iOS

Författare: IT Sectr Publicerad: 2026-02-27 Lästid: 8 min
Gesture Recognizer — en abstraktion i UIKit som omvandlar en sekvens av användarens beröringar till en igenkänd gest: tap, svep, lång tryckning, nypning eller rotation. Istället för manuell spårning av koordinater i metoderna touchesBegan/touchesMoved lägger utvecklaren till ett färdigt UIGestureRecognizer-objekt till UIView och implementerar en action-metod. Enligt Apple Developer Documentation stöder UIGestureRecognizer 7 inbyggda underklasser som täcker 95% av typiska gester i mobila applikationer.

Huvudpunkter

  • UIGestureRecognizer — abstrakt UIKit-klass för igenkänning av beröringsmönster: taps, svep, nypningar, rotationer och långa tryckningar.
  • 7 inbyggda underklasser: UITapGestureRecognizer, UISwipeGestureRecognizer, UIPinchGestureRecognizer, UIRotationGestureRecognizer, UILongPressGestureRecognizer, UIPanGestureRecognizer, UIScreenEdgePanGestureRecognizer.
  • Varje igenkännare har ett tillstånd (possible, began, changed, ended, cancelled, failed) som uppdateras när fingrarna rör sig.
  • För att lösa konflikter mellan gester används metoden require(toFail:), som ställer in prioriteringen för igenkänning.
  • Gesture Recognizer fungerar med UIKit och UIViewRepresentable i SwiftUI, men i inbyggt SwiftUI används gestmodifierare.

Vad är Gesture Recognizer?

UIGestureRecognizer — en abstrakt basklass i UIKit som delar upp gestigenkänningsprocessen i separata objekt. Varje underklass ansvarar för en gesttyp: UITapGestureRecognizer — för tap med ett visst antal fingrar, UISwipeGestureRecognizer — för svep i en given riktning. Utvecklaren lägger till igenkännaren på UIView via metoden addGestureRecognizer(:), och UIKit spårar automatiskt beröringar, uppdaterar tillståndet och anropar åtgärden vid igenkänning.

Innan UIGestureRecognizer kom (iOS 3.2, 2010) överskrev utvecklare UIResponder-metoderna — touchesBegan, touchesMoved, touchesEnded — och analyserade manuellt beröringarnas bana. Detta ledde till kodduplicering och fel vid bearbetning av samtidiga beröringar. Apple kapslade in denna logik i UIGestureRecognizer och lade till stöd för multitouch, annullering av gester och samtidig funktion av flera igenkännare på en vy.

Enligt WWDC-sessioner bearbetar Gesture Recognizer upp till 11 samtidiga beröringar på iPad och 5 på iPhone. På IT Sectr använder vi UIGestureRecognizer som standardsättet för att hantera användarinmatning i alla UIKit-projekt — detta har eliminerat buggar relaterade till manuell spårning av touchesBegan.

UIGestureRecognizer tillstånd

Varje UIGestureRecognizer går igenom 7 möjliga tillstånd, definierade i enumet UIGestureRecognizer.State. Dessa tillstånd reflekterar igenkänningslivscykeln: från detektering av beröring till slutförande eller annullering av gesten. Att förstå tillstånden är avgörande för att implementera anpassade igenkännare och felsöka konflikter.

Tillstånd Betydelse När uppstår
.possible Initialt tillstånd, gesten har inte identifierats än Omedelbart efter tillägg till vyn
.began Gesten har identifierats och börjat utföras Vid första fingerrörelsen för pan/longPress
.changed Gestparametrar har ändrats (koordinater, vinkel) Vid varje fingerrörelse
.ended Användaren har lyft fingret, gesten slutförd Vid touchesEnded
.cancelled Gesten avbruten av systemet (inkommande samtal, orienteringsändring) Vid touchesCancelled
.failed Gesten inte identifierad enligt villkoren Vid touchesCancelled utan identifiering
.recognized Synonym för .ended; gesten har identifierats framgångsrikt Samma som .ended

Diskreta gester (tap, swipe) går från .possible direkt till .ended eller .failed. Kontinuerliga gester (pan, pinch, rotation, longPress) går igenom .possible → .began → .changed (flera gånger) → .ended. I åtgärdsmetoden, kontrollera gestureRecognizer.state — detta gör det möjligt att skilja mellan början, förändring och slut av gesten.

Typer av gester i iOS

UIKit tillhandahåller 7 inbyggda underklasser av UIGestureRecognizer, som täcker de flesta interaktionsscenarier. Varje underklass har specifika inställningar: numberOfTapsRequired för tap, direction för svep, minimumPressDuration för lång tryckning.

  • UITapGestureRecognizer — identifierar enkla och flera taps. Antalet beröringar (numberOfTapsRequired) och fingrar (numberOfTouchesRequired) kan konfigureras. Används för knappar, länkar, val av element.
  • UISwipeGestureRecognizer — identifierar svep i en av fyra riktningar (right, left, up, down). Egenskapen direction anger riktningen; numberOfTouchesRequired — antalet fingrar.
  • UIPanGestureRecognizer — kontinuerlig gest för dragning. Metoden translation(in:) returnerar förskjutningen från startpunkten. Används för drag-and-drop, karuseller, pull-to-refresh.
  • UIPinchGestureRecognizer — skalning med två fingrar. Egenskapen scale återspeglar den aktuella skalningsfaktorn. Detaljerat beskriven i artikeln Pinch-to-Zoom.
  • UIRotationGestureRecognizer — rotation med två fingrar. Egenskapen rotation lagrar vinkeln i radianer. Används för att rotera bilder, kartor, canvasser.
  • UILongPressGestureRecognizer — lång tryckning. Parametrar minimumPressDuration (sekunder), allowableMovement (pixlar). Används för kontextmenyer, dragning av element.
  • UIScreenEdgePanGestureRecognizer — panorering från skärmkanten. Egenskapen edges anger vilken kant som ska spåras. Används för navigationsgester, notifikationsgardiner.

För anpassade gester (t.ex. ritning av sicksack) skapas en underklass av UIGestureRecognizer med överskridning av metoderna touchesBegan, touchesMoved, touchesEnded och uppdatering av tillstånd. Apple rekommenderar att använda inbyggda klasser där det är möjligt — de är optimerade och interagerar korrekt med varandra.

Lösa konflikter mellan gester

När flera UIGestureRecognizer används på en UIView (t.ex. tap och double-tap), uppstår en igenkänningskonflikt: vid dubbeltap aktiveras först den enkla tapen. Som lösning tillhandahåller Apple metoden require(toFail:), som fördröjer igenkänningen av en gest tills den andra misslyckas.

Mekanismen fungerar så här: genom att anropa tapRecognizer.require(toFail: doubleTapRecognizer) anger du att tapRecogniser övergår till tillståndet .recognized först efter att doubleTapRecogniser har avslutats i .failed. Detta lägger till en fördröjning på ~0,3 sekunder före utförandet av den enkla tapen — användaren trycker två gånger och den första tapen ignoreras. En alternativ metod — delegaten UIGestureRecognizerDelegate med metoden gestureRecognizer(_:shouldRecognizeSimultaneouslyWith:), som tillåter samtidig igenkänning (t.ex. pan + pinch för en karta).

Enligt WWDC 2020 är cirka 15% av buggarna i UIKit-appar relaterade till felaktig konfiguration av gestkonflikter. På IT Sectr har vi standardiserat tillvägagångssättet: för varje skärm skapas ett gestschema med require(toFail:)-prioriteter — detta har helt eliminerat buggar med dubbelaktivering av taps.

Kodexempel i Swift

Exempel 1: UITapGestureRecognizer — tap på bild

Lägger till en hanterare för enkel tap på UIImageView. Vid tap ändrar bilden sin genomskinlighet — det enklaste exemplet som visar bindning av en gest till en vy.

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

Viktig punkt: isUserInteractionEnabled på UIImageView är som standard false — utan denna flagga kommer Gesture Recognizer inte att ta emot beröringar. För UIView och UIButton är flaggan som standard aktiverad. Åtgärdsmetoden tar emot en UITapGestureRecognizer-parameter genom vilken location(in:) kan erhållas för att bestämma tapens koordinater.

Exempel 2: UISwipeGestureRecognizer — svep för navigering

Implementerar svep åt vänster för att återgå till föregående skärm. Demonstrerar konfiguration av riktning och bindning av gesten till kontrollerns rotvy.

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 — en diskret gest: den övergår till .recognised omedelbart efter identifiering, utan mellanliggande .changed. Därför behöver tillståndet inte kontrolleras i åtgärden — gesten antingen identifieras (åtgärden anropas) eller inte. Egenskapen direction accepterar ett av fyra värden: .left, .right, .up, .down. För att stödja flera riktningar, skapa separata igenkännare för varje riktning.

Exempel 3: Kombination av gester med require(toFail:)

Visar hur man konfigurerar enkel och dubbel tap på samma vy utan konflikt. Igenkännaren för dubbel tap har prioritet — den enkla tapen aktiveras endast om den dubbla tapen inte identifieras.

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

Utan require(toFail:) anropas först handleSingleTap, sedan handleDoubleTap vid dubbeltap — detta förstör användarupplevelsen. Med require(toFail:) väntar den enkla tapen ~0,3 sekunder för att försäkra sig om att den andra tapen inte följer. På IT Sectr används detta mönster i bildredigerare och gallerier, där dubbeltap zoomar in och enkel tap väljer ett element.

Vanliga frågor

Kan flera Gesture Recognizer användas på en vy?

Ja, UIView stöder flera UIGestureRecognizer samtidigt. För att lösa konflikter, använd metoden require(toFail:), som anger ordningen för igenkänning. För parallell funktion av gester (t.ex. pan + pinch på en karta) implementera delegaten gestureRecognizer(_:shouldRecognizeSimultaneouslyWith:), som returnerar true.

Vad skiljer UIGestureRecognizer från touchesBegan?

UIGestureRecognizer — en högnivåabstraktion som automatiskt identifierar beröringsmönster och hanterar tillstånd. touchesBegan — en lågnivåmetod i UIResponder som kräver manuell spårning av koordinater, timing och annullering av beröringar. Gesture Recognizer är enklare, mer pålitlig och att föredra för standardgester; touchesBegan är bara motiverad för anpassad grafik.

Fungerar Gesture Recognizer i SwiftUI?

I inbyggt SwiftUI används modifierare: onTapGesture, onLongPressGesture, DragGesture, MagnificationGesture, RotationGesture. Dessa är deklarativa motsvarigheter till UIGestureRecognizer, integrerade i SwiftUI-hierarkin. Vid behov kan en UIKit-igenkännare lindas in via UIViewRepresentable, men Apple rekommenderar att använda inbyggda SwiftUI-gester.

Sammanfattning

  • UIGestureRecognizer — UIKit-abstraktion för att dela upp gestigenkänningslogik i separata objekt med automatisk tillståndshantering.
  • 7 inbyggda underklasser täcker 95% av typiska gester: tap, svep, panorering, nypning, rotation, lång tryckning och svep från kanten.
  • Varje igenkännare går igenom 7 tillstånd — från .possible till .ended/.failed, vilket möjliggör exakt spårning av diskreta och kontinuerliga gester.
  • Metoden require(toFail:) löser konflikter mellan gester på samma vy genom att ange prioritet för igenkänning.
  • I SwiftUI används deklarativa gestmodifierare, men UIKit-igenkännare är tillgängliga via UIViewRepresentable.
  • Gesture Recognizer är obligatorisk för UIKit-projekt; touchesBegan är bara motiverad för anpassad ritning och lågnivågrafik.
  • Använd require(toFail:) för tap/double-tap-par och gestureRecognizer(_:shouldRecognizeSimultaneouslyWith:) för parallella gester.

Vi utvecklar en mobil applikation nyckelfärdigt

IT Sectr skapar iOS- och Android-applikationer för startups och företag sedan 2017. Vi ger dig råd och föreslår den bästa lösningen.

Diskutera projektet

Läs också