Gesture Recognizer — ano ito, pagproseso ng pagpindot sa iOS

May-akda: IT Sectr Nai-publish: 2026-02-27 Oras ng pagbabasa: 8 min
Gesture Recognizer — isang abstraksyon sa UIKit na nagko-convert ng pagkakasunod-sunod ng mga pagpindot ng gumagamit sa isang nakilalang kilos: tap, swipe, matagal na pindot, pinch, o pag-ikot. Sa halip na manu-manong subaybayan ang mga coordinate sa mga pamamaraang touchesBegan/touchesMoved, ang developer ay nagdaragdag ng handa nang UIGestureRecognizer na bagay sa UIView at nagpapatupad ng action method. Ayon sa Apple Developer Documentation, ang UIGestureRecognizer ay sumusuporta sa 7 built-in na subclass na sumasaklaw sa 95% ng mga tipikal na kilos sa mga mobile app.

Mga pangunahing punto

  • UIGestureRecognizer — abstract na klase ng UIKit para sa pagkilala ng mga pattern ng pagpindot: mga tap, swipe, pinch, pag-ikot, at matagal na pindot.
  • 7 built-in na subclass: UITapGestureRecognizer, UISwipeGestureRecognizer, UIPinchGestureRecognizer, UIRotationGestureRecognizer, UILongPressGestureRecognizer, UIPanGestureRecognizer, UIScreenEdgePanGestureRecognizer.
  • Bawat tagakilala ay may estado (possible, began, changed, ended, cancelled, failed) na ina-update habang gumagalaw ang mga daliri.
  • Para sa paglutas ng mga salungatan sa pagitan ng mga kilos, ginagamit ang pamamaraang require(toFail:), na nagtatakda ng priyoridad ng pagkilala.
  • Gumagana ang Gesture Recognizer sa UIKit at UIViewRepresentable sa SwiftUI, ngunit sa native na SwiftUI ay ginagamit ang mga modifier ng kilos.

Ano ang Gesture Recognizer?

UIGestureRecognizer — isang abstract na base class sa UIKit na nagde-decompose ng proseso ng pagkilala ng kilos sa magkakahiwalay na bagay. Bawat subclass ay responsable para sa isang uri ng kilos: UITapGestureRecognizer — para sa tap na may tiyak na bilang ng mga daliri, UISwipeGestureRecognizer — para sa swipe sa isang tiyak na direksyon. Ang developer ay nagdaragdag ng tagakilala sa UIView sa pamamagitan ng pamamaraang addGestureRecognizer(:), at awtomatikong sinusubaybayan ng UIKit ang mga pagpindot, ina-update ang estado, at tinatawagan ang aksyon sa pagkilala.

Bago ang pagdating ng UIGestureRecognizer (iOS 3.2, 2010), ang mga developer ay nag-o-override ng mga pamamaraan ng UIResponder — touchesBegan, touchesMoved, touchesEnded — at manu-manong sinusuri ang trajectory ng mga pagpindot. Ito ay humantong sa pagdoble ng code at mga error sa pagproseso ng sabay-sabay na pagpindot. In-encapsulate ng Apple ang lohika na ito sa UIGestureRecognizer, nagdagdag ng suporta para sa multitouch, pagkansela ng mga kilos, at sabay-sabay na pagtatrabaho ng maraming tagakilala sa isang view.

Ayon sa mga sesyon ng WWDC, pinoproseso ng Gesture Recognizer ang hanggang 11 sabay-sabay na pagpindot sa iPad at 5 sa iPhone. Sa IT Sectr, ginagamit namin ang UIGestureRecognizer bilang karaniwang paraan ng pagproseso ng input ng gumagamit sa lahat ng UIKit na proyekto — inalis nito ang mga bug na may kaugnayan sa manu-manong pagsubaybay ng touchesBegan.

Mga estado ng UIGestureRecognizer

Bawat UIGestureRecognizer ay dumadaan sa 7 posibleng estado, na tinukoy sa enum na UIGestureRecognizer.State. Ang mga estadong ito ay sumasalamin sa lifecycle ng pagkilala: mula sa pagtuklas ng pagpindot hanggang sa pagkumpleto o pagkansela ng kilos. Ang pag-unawa sa mga estado ay kritikal para sa pagpapatupad ng mga custom na tagakilala at pag-debug ng mga salungatan.

Estado Kahulugan Kailan nagaganap
.possible Paunang estado, hindi pa nakikilala ang kilos Kaagad pagkatapos idagdag sa view
.began Nakilala ang kilos at nagsimulang isagawa Sa unang galaw ng daliri para sa pan/longPress
.changed Nagbago ang mga parameter ng kilos (coordinate, anggulo) Sa bawat galaw ng daliri
.ended Inalis ng gumagamit ang daliri, natapos ang kilos Sa touchesEnded
.cancelled Ang kilos ay naantala ng system (papasok na tawag, pagbabago ng oryentasyon) Sa touchesCancelled
.failed Hindi nakilala ang kilos ayon sa mga kondisyon Sa touchesCancelled na walang pagkilala
.recognized Kasingkahulugan ng .ended; matagumpay na nakilala ang kilos Kapareho ng .ended

Ang mga discrete na kilos (tap, swipe) ay lumilipat mula .possible direkta sa .ended o .failed. Ang mga tuluy-tuloy na kilos (pan, pinch, rotation, longPress) ay dumadaan sa .possible → .began → .changed (paulit-ulit) → .ended. Sa action method, suriin ang gestureRecognizer.state — pinapayagan nito na makilala ang simula, pagbabago, at pagtatapos ng kilos.

Mga uri ng kilos sa iOS

Ang UIKit ay nagbibigay ng 7 built-in na subclass ng UIGestureRecognizer, na sumasaklaw sa karamihan ng mga senaryo ng interaksyon. Bawat subclass ay may mga tiyak na setting: numberOfTapsRequired para sa tap, direction para sa swipe, minimumPressDuration para sa matagal na pindot.

  • UITapGestureRecognizer — kumikilala ng isahan at maramihang tap. Nako-configure ang bilang ng mga pagpindot (numberOfTapsRequired) at mga daliri (numberOfTouchesRequired). Ginagamit para sa mga button, link, pagpili ng elemento.
  • UISwipeGestureRecognizer — kumikilala ng swipe sa isa sa apat na direksyon (right, left, up, down). Ang property na direction ay nagtatakda ng direksyon; numberOfTouchesRequired — bilang ng mga daliri.
  • UIPanGestureRecognizer — tuluy-tuloy na kilos para sa pag-drag. Ang pamamaraang translation(in:) ay nagbabalik ng displacement mula sa panimulang punto. Ginagamit para sa drag-and-drop, mga carousel, pull-to-refresh.
  • UIPinchGestureRecognizer — pag-scale gamit ang dalawang daliri. Ang property na scale ay sumasalamin sa kasalukuyang scale factor. Detalyadong tinalakay sa artikulong Pinch-to-Zoom.
  • UIRotationGestureRecognizer — pag-ikot gamit ang dalawang daliri. Ang property na rotation ay nag-iimbak ng anggulo sa radians. Ginagamit para sa pag-ikot ng mga larawan, mapa, canvas.
  • UILongPressGestureRecognizer — matagal na pindot. Mga parameter na minimumPressDuration (segundo), allowableMovement (pixel). Ginagamit para sa mga context menu, pag-drag ng mga elemento.
  • UIScreenEdgePanGestureRecognizer — pan mula sa gilid ng screen. Ang property na edges ay tumutukoy kung aling gilid ang susubaybayan. Ginagamit para sa mga kilos ng nabigasyon, mga kurtina ng notipikasyon.

Para sa mga custom na kilos (halimbawa, pagguhit ng zigzag), gumawa ng subclass ng UIGestureRecognizer na may override ng mga pamamaraang touchesBegan, touchesMoved, touchesEnded at pag-update ng estado. Inirerekomenda ng Apple na gamitin ang mga built-in na klase kung saan posible — ang mga ito ay na-optimize at wastong nakikipag-ugnayan sa isa't isa.

Paglutas ng mga salungatan sa pagitan ng mga kilos

Kapag maraming UIGestureRecognizer ang ginagamit sa isang UIView (halimbawa, tap at double-tap), nagaganap ang isang salungatan sa pagkilala: sa dobleng tap, unang nag-trigger ang isahang tap. Para sa solusyon, nagbibigay ang Apple ng pamamaraang require(toFail:), na nagpapabagal sa pagkilala ng isang kilos hanggang sa mabigo ang isa pa.

Gumagana ang mekanismo tulad sumusunod: sa pagtawag ng tapRecognizer.require(toFail: doubleTapRecognizer), tinutukoy mo na ang tapRecogniser ay lilipat sa estadong .recognized pagkatapos lamang matapos ang doubleTapRecogniser sa .failed. Nagdaragdag ito ng pagkaantala na ~0.3 segundo bago isagawa ang isahang tap — dalawang beses pumipindot ang gumagamit, at ang unang tap ay hindi pinapansin. Ang alternatibong pamamaraan — ang delegate na UIGestureRecognizerDelegate na may pamamaraang gestureRecognizer(_:shouldRecognizeSimultaneouslyWith:), na nagpapahintulot ng sabay-sabay na pagkilala (halimbawa, pan + pinch para sa mapa).

Ayon sa WWDC 2020, humigit-kumulang 15% ng mga bug sa mga UIKit app ay may kaugnayan sa maling configuration ng mga salungatan ng kilos. Sa IT Sectr, na-standardize namin ang diskarte: para sa bawat screen, ginagawa ang isang scheme ng kilos na may mga priyoridad ng require(toFail:) — ganap nitong inalis ang mga bug na may dobleng pag-trigger ng mga tap.

Mga halimbawa ng code sa Swift

Halimbawa 1: UITapGestureRecognizer — tap sa larawan

Nagdaragdag ng handler ng isahang tap sa UIImageView. Kapag na-tap, binabago ng larawan ang transparency — ang pinakasimpleng halimbawa na nagpapakita ng pag-ugnay ng kilos sa view.

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

Mahalagang punto: ang isUserInteractionEnabled sa UIImageView ay default na false — kung wala ang flag na ito, hindi makakatanggap ng mga pagpindot ang Gesture Recognizer. Para sa UIView at UIButton, ang flag ay default na naka-enable. Ang action method ay tumatanggap ng parameter na UITapGestureRecognizer kung saan maaaring makuha ang location(in:) para sa pagtukoy ng mga coordinate ng tap.

Halimbawa 2: UISwipeGestureRecognizer — swipe para sa nabigasyon

Nagpapatupad ng swipe sa kaliwa para bumalik sa nakaraang screen. Nagpapakita ng configuration ng direksyon at pag-ugnay ng kilos sa root view ng 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)
    }
}

Ang UISwipeGestureRecognizer — ay isang discrete na kilos: lumilipat ito sa .recognised kaagad pagkatapos makilala, nang walang intermediate na .changed. Kaya naman sa aksyon hindi na kailangang suriin ang estado — ang kilos ay maaaring makilala (tatawagin ang aksyon) o hindi. Ang property na direction ay tumatanggap ng isa sa apat na halaga: .left, .right, .up, .down. Para suportahan ang maraming direksyon, gumawa ng hiwalay na mga tagakilala para sa bawat isa.

Halimbawa 3: Kombinasyon ng mga kilos na may require(toFail:)

Nagpapakita kung paano i-configure ang isahan at dobleng tap sa parehong view nang walang salungatan. Ang tagakilala ng dobleng tap ay may priyoridad — ang isahang tap ay nag-trigger lamang kung ang dobleng tap ay hindi nakilala.

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

Kung walang require(toFail:), sa dobleng tap, unang tatawagin ang handleSingleTap, pagkatapos ang handleDoubleTap — sinisira nito ang UX. Sa require(toFail:), ang isahang tap ay naghihintay ng ~0.3 segundo upang matiyak na hindi susunod ang pangalawang tap. Sa IT Sectr, ang pattern na ito ay ginagamit sa mga editor ng larawan at gallery, kung saan ang dobleng tap ay nag-zoom in, at ang isahang tap ay pumipili ng elemento.

Mga madalas itanong

Maaari bang gumamit ng maraming Gesture Recognizer sa isang view?

Oo, sinusuportahan ng UIView ang maraming UIGestureRecognizer nang sabay-sabay. Para sa paglutas ng mga salungatan, gamitin ang pamamaraang require(toFail:), na nagtatakda ng pagkakasunod-sunod ng pagkilala. Para sa parallel na pagtatrabaho ng mga kilos (halimbawa, pan + pinch sa mapa), ipatupad ang delegate na gestureRecognizer(_:shouldRecognizeSimultaneouslyWith:), na nagbabalik ng true.

Ano ang pagkakaiba ng UIGestureRecognizer sa touchesBegan?

UIGestureRecognizer — isang mataas na antas na abstraksyon na awtomatikong kumikilala ng mga pattern ng pagpindot at namamahala ng mga estado. Ang touchesBegan — ay isang mababang antas na pamamaraan ng UIResponder na nangangailangan ng manu-manong pagsubaybay ng mga coordinate, timing, at pagkansela ng mga pagpindot. Ang Gesture Recognizer ay mas simple, mas maaasahan, at mas mainam para sa mga karaniwang kilos; ang touchesBegan ay makatwiran lamang para sa custom na graphics.

Gumagana ba ang Gesture Recognizer sa SwiftUI?

Sa native na SwiftUI, ginagamit ang mga modifier: onTapGesture, onLongPressGesture, DragGesture, MagnificationGesture, RotationGesture. Ang mga ito ay deklaratibong katapat ng UIGestureRecognizer, na isinama sa hierarchy ng SwiftUI. Kung kinakailangan, maaaring balutin ang UIKit tagakilala sa pamamagitan ng UIViewRepresentable, ngunit inirerekomenda ng Apple ang paggamit ng native na SwiftUI na mga kilos.

Buod

  • UIGestureRecognizer — abstraksyon ng UIKit para sa pag-decompose ng lohika ng pagkilala ng kilos sa magkakahiwalay na bagay na may awtomatikong pamamahala ng estado.
  • 7 built-in na subclass ay sumasaklaw sa 95% ng mga tipikal na kilos: tap, swipe, pan, pinch, pag-ikot, matagal na pindot, at swipe mula sa gilid.
  • Bawat tagakilala ay dumadaan sa 7 estado — mula .possible hanggang .ended/.failed, na nagpapahintulot ng tumpak na pagsubaybay ng mga discrete at tuluy-tuloy na kilos.
  • Ang pamamaraang require(toFail:) ay lumulutas ng mga salungatan sa pagitan ng mga kilos sa parehong view, nagtatakda ng priyoridad ng pagkilala.
  • Sa SwiftUI, ginagamit ang mga deklaratibong modifier ng kilos, ngunit ang mga tagakilala ng UIKit ay maaaring ma-access sa pamamagitan ng UIViewRepresentable.
  • Ang Gesture Recognizer ay sapilitan para sa mga proyekto ng UIKit; ang touchesBegan ay makatwiran lamang para sa custom na pagguhit at mababang antas na graphics.
  • Gamitin ang require(toFail:) para sa mga pares ng tap/double-tap at gestureRecognizer(_:shouldRecognizeSimultaneouslyWith:) para sa mga parallel na kilos.

Gagawa kami ng mobile application na turnkey

Gumagawa ang IT Sectr ng mga iOS at Android application para sa mga startup at negosyo mula noong 2017. Magpapayo kami sa iyo at magmumungkahi ng pinakamahusay na solusyon.

Pag-usapan ang proyekto

Basahin din