Gesture Recognizer — এটি কী, iOS-এ টাচ হ্যান্ডলিং

লেখক: IT Sectr প্রকাশিত: 2026-02-27 পড়ার সময়: 8 মিনিট
Gesture Recognizer হল UIKit-এর একটি অ্যাবস্ট্রাকশন যা ব্যবহারকারীর স্পর্শের ক্রমকে একটি স্বীকৃত জেসচারে রূপান্তরিত করে: ট্যাপ, সোয়াইপ, লং প্রেস, পিঞ্চ বা রোটেশন। touchesBegan/touchesMoved মেথডে ম্যানুয়ালি কোঅর্ডিনেট ট্র্যাক করার পরিবর্তে, ডেভেলপার UIView-এ একটি প্রস্তুত UIGestureRecognizer অবজেক্ট যোগ করে এবং একটি অ্যাকশন মেথড ইমপ্লিমেন্ট করে। Apple Developer Documentation অনুসারে, UIGestureRecognizer 7টি বিল্ট-ইন সাবক্লাস সাপোর্ট করে যা মোবাইল অ্যাপ্লিকেশনে 95% সাধারণ জেসচার কভার করে।

মূল বিষয়

  • UIGestureRecognizer হল স্পর্শ প্যাটার্ন শনাক্ত করার জন্য UIKit-এর একটি অ্যাবস্ট্রাক্ট ক্লাস: ট্যাপ, সোয়াইপ, পিঞ্চ, রোটেশন এবং লং প্রেস।
  • 7টি বিল্ট-ইন সাবক্লাস: UITapGestureRecognizer, UISwipeGestureRecognizer, UIPinchGestureRecognizer, UIRotationGestureRecognizer, UILongPressGestureRecognizer, UIPanGestureRecognizer, UIScreenEdgePanGestureRecognizer।
  • প্রতিটি রিকগনাইজারের একটি অবস্থা (possible, began, changed, ended, cancelled, failed) থাকে যা আঙ্গুল চলার সাথে সাথে আপডেট হয়।
  • জেসচারের মধ্যে দ্বন্দ্ব সমাধানের জন্য require(toFail:) মেথড ব্যবহার করা হয় যা শনাক্তকরণ অগ্রাধিকার নির্ধারণ করে।
  • Gesture Recognizer SwiftUI-তে UIKit এবং UIViewRepresentable-এর সাথে কাজ করে, কিন্তু নেটিভ SwiftUI জেসচার মডিফায়ার ব্যবহার করে।

Gesture Recognizer কী?

UIGestureRecognizer হল UIKit-এর একটি অ্যাবস্ট্রাক্ট বেস ক্লাস যা জেসচার শনাক্তকরণ প্রক্রিয়াকে পৃথক অবজেক্টে বিভক্ত করে। প্রতিটি সাবক্লাস একটি জেসচার প্রকার হ্যান্ডল করে: UITapGestureRecognizer নির্দিষ্ট সংখ্যক স্পর্শের ট্যাপ হ্যান্ডল করে, UISwipeGestureRecognizer একটি নির্দিষ্ট দিকে সোয়াইপ হ্যান্ডল করে। ডেভেলপার addGestureRecognizer(:) মেথডের মাধ্যমে UIView-এ রিকগনাইজার যোগ করে, এবং UIKit স্বয়ংক্রিয়ভাবে স্পর্শ ট্র্যাক করে, অবস্থা আপডেট করে এবং শনাক্তকরণে অ্যাকশন কল করে।

UIGestureRecognizer (iOS 3.2, 2010)-এর আগে, ডেভেলপাররা UIResponder মেথড — touchesBegan, touchesMoved, touchesEnded — ওভাররাইড করত এবং ম্যানুয়ালি স্পর্শের পথ বিশ্লেষণ করত। এর ফলে কোড ডুপ্লিকেশন এবং একসঙ্গে একাধিক স্পর্শ হ্যান্ডল করতে ত্রুটি হত। Apple এই লজিক UIGestureRecognizer-এ এনক্যাপসুলেট করেছে, মাল্টিটাচ, জেসচার বাতিল এবং একটি ভিউতে একাধিক রিকগনাইজারের একসঙ্গে পরিচালনার সমর্থন যোগ করেছে।

WWDC সেশন অনুসারে, Gesture Recognizer iPad-এ 11টি একসঙ্গে স্পর্শ এবং iPhone-এ 5টি হ্যান্ডল করে। IT Sectr-এ, আমরা সব UIKit প্রকল্পে ব্যবহারকারী ইনপুট হ্যান্ডল করার মানক উপায় হিসেবে UIGestureRecognizer ব্যবহার করি — এটি ম্যানুয়াল touchesBegan ট্র্যাকিংয়ের সাথে সম্পর্কিত বাগ দূর করেছে।

UIGestureRecognizer-এর অবস্থাসমূহ

প্রতিটি UIGestureRecognizer 7টি সম্ভাব্য অবস্থার মধ্য দিয়ে যায়, যা UIGestureRecognizer.State এনামে সংজ্ঞায়িত। এই অবস্থাগুলি শনাক্তকরণ জীবনচক্র প্রতিফলিত করে: স্পর্শ সনাক্তকরণ থেকে সম্পূর্ণ বা বাতিল হওয়া পর্যন্ত। কাস্টম রিকগনাইজার ইমপ্লিমেন্ট এবং দ্বন্দ্ব ডিবাগ করার জন্য অবস্থা বোঝা গুরুত্বপূর্ণ।

অবস্থা অর্থ কখন ঘটে
.possible প্রাথমিক অবস্থা, জেসচার এখনও শনাক্ত হয়নি ভিউতে যোগ করার সাথে সাথেই
.began জেসচার শনাক্ত হয়েছে এবং কার্যকর করা শুরু হয়েছে pan/longPress-এর জন্য প্রথম আঙুল নড়াচড়ায়
.changed জেসচার প্যারামিটার পরিবর্তিত হয়েছে (কোঅর্ডিনেট, কোণ) প্রতিটি আঙুল নড়াচড়ায়
.ended ব্যবহারকারী আঙুল তুলেছেন, জেসচার সম্পন্ন touchesEnded-এ
.cancelled জেসচার সিস্টেম দ্বারা বাধাপ্রাপ্ত (ইনকামিং কল, ওরিয়েন্টেশন পরিবর্তন) touchesCancelled-এ
.failed শর্ত অনুযায়ী জেসচার শনাক্ত হয়নি শনাক্তকরণ ছাড়া touchesCancelled-এ
.recognized .ended-এর সমার্থক; জেসচার সফলভাবে শনাক্ত হয়েছে .ended-এর মতোই

ডিসক্রিট জেসচার (tap, swipe) .possible থেকে সরাসরি .ended বা .failed-এ যায়। কন্টিনিউয়াস জেসচার (pan, pinch, rotation, longPress) .possible → .began → .changed (পুনরাবৃত্ত) → .ended-এর মধ্য দিয়ে যায়। অ্যাকশন মেথডে gestureRecognizer.state চেক করুন — এটি জেসচারের শুরু, পরিবর্তন এবং শেষ আলাদা করতে দেয়।

iOS-এ জেসচারের প্রকারভেদ

UIKit 7টি বিল্ট-ইন UIGestureRecognizer সাবক্লাস প্রদান করে, যা অধিকাংশ ইন্টারঅ্যাকশন পরিস্থিতি কভার করে। প্রতিটি সাবক্লাসের নির্দিষ্ট সেটিংস রয়েছে: ট্যাপের জন্য numberOfTapsRequired, সোয়াইপের জন্য direction, লং প্রেসের জন্য minimumPressDuration।

  • UITapGestureRecognizer — একক এবং একাধিক ট্যাপ শনাক্ত করে। ট্যাপের সংখ্যা (numberOfTapsRequired) এবং আঙ্গুলের সংখ্যা (numberOfTouchesRequired) কনফিগারযোগ্য। বাটন, লিংক, এলিমেন্ট নির্বাচনের জন্য ব্যবহৃত হয়।
  • UISwipeGestureRecognizer — চারটি দিকের একটিতে সোয়াইপ শনাক্ত করে (right, left, up, down)। direction প্রপার্টি দিক নির্ধারণ করে; numberOfTouchesRequired আঙ্গুলের সংখ্যা নির্ধারণ করে।
  • UIPanGestureRecognizer — ড্র্যাগ করার জন্য কন্টিনিউয়াস জেসচার। translation(in:) মেথড প্রারম্ভিক বিন্দু থেকে অফসেট রিটার্ন করে। ড্র্যাগ-এন্ড-ড্রপ, ক্যারোজেল, পুল-টু-রিফ্রেশের জন্য ব্যবহৃত হয়।
  • UIPinchGestureRecognizer — দুটি আঙুল দিয়ে স্কেলিং। scale প্রপার্টি বর্তমান স্কেল ফ্যাক্টর প্রতিফলিত করে। Pinch-to-Zoom নিবন্ধে বিস্তারিত বর্ণিত।
  • UIRotationGestureRecognizer — দুটি আঙুল দিয়ে ঘূর্ণন। rotation প্রপার্টি রেডিয়ানে কোণ সংরক্ষণ করে। ছবি, মানচিত্র, ক্যানভাস ঘোরানোর জন্য ব্যবহৃত হয়।
  • UILongPressGestureRecognizer — লং প্রেস। প্যারামিটার: minimumPressDuration (সেকেন্ড), allowableMovement (পিক্সেল)। কনটেক্সট মেনু, এলিমেন্ট ড্র্যাগিংয়ের জন্য ব্যবহৃত হয়।
  • UIScreenEdgePanGestureRecognizer — স্ক্রিনের কিনারা থেকে প্যান করা। edges প্রপার্টি নির্দিষ্ট করে কোন কিনারা ট্র্যাক করতে হবে। নেভিগেশন জেসচার, নোটিফিকেশন প্যানেলের জন্য ব্যবহৃত হয়।

কাস্টম জেসচারের জন্য (যেমন, জিগজ্যাগ আঁকা), touchesBegan, touchesMoved, touchesEnded ওভাররাইড করে এবং অবস্থা আপডেট করে UIGestureRecognizer-এর সাবক্লাস তৈরি করা হয়। Apple যেখানে সম্ভব বিল্ট-ইন ক্লাস ব্যবহার করার পরামর্শ দেয় — সেগুলি অপ্টিমাইজড এবং একে অপরের সাথে সঠিকভাবে ইন্টারঅ্যাক্ট করে।

জেসচারের মধ্যে দ্বন্দ্ব সমাধান

যখন একটি UIView-এ একাধিক UIGestureRecognizer ব্যবহার করা হয় (যেমন, ট্যাপ এবং ডাবল-ট্যাপ), তখন একটি শনাক্তকরণ দ্বন্দ্ব ঘটে: ডাবল ট্যাপে, সিঙ্গেল ট্যাপ প্রথমে ফায়ার করে। Apple একটি জেসচারের শনাক্তকরণ বিলম্বিত করার জন্য require(toFail:) মেথড প্রদান করে যতক্ষণ না অন্যটি ব্যর্থ হয়।

প্রক্রিয়াটি এভাবে কাজ করে: tapRecognizer.require(toFail: doubleTapRecognizer) কল করে, আপনি নির্দিষ্ট করেন যে tapRecognizer .recognized অবস্থায় যাবে শুধুমাত্র doubleTapRecognizer .failed-এ শেষ হওয়ার পর। এটি সিঙ্গেল ট্যাপ কার্যকর করার আগে ~0.3 সেকেন্ড বিলম্ব যোগ করে — ব্যবহারকারী দুবার ট্যাপ করে, এবং প্রথম ট্যাপ উপেক্ষিত হয়। বিকল্প পদ্ধতি হল UIGestureRecognizerDelegate যার gestureRecognizer(_:shouldRecognizeSimultaneouslyWith:) মেথড রয়েছে, যা একসঙ্গে শনাক্তকরণের অনুমতি দেয় (যেমন, ম্যাপের জন্য pan + pinch)।

WWDC 2020 অনুসারে, UIKit অ্যাপ্লিকেশনে প্রায় 15% বাগ জেসচার দ্বন্দ্বের ভুল কনফিগারেশনের সাথে সম্পর্কিত। IT Sectr-এ, আমরা পদ্ধতিটি মানক করেছি: প্রতিটি স্ক্রিনে require(toFail:) অগ্রাধিকার সহ একটি জেসচার স্কিম রয়েছে — এটি ডাবল-ট্যাপ ফায়ারিং বাগ সম্পূর্ণরূপে দূর করেছে।

Swift-এ কোড উদাহরণ

উদাহরণ 1: UITapGestureRecognizer — ছবিতে ট্যাপ

UIImageView-তে একটি সিঙ্গেল ট্যাপ হ্যান্ডলার যোগ করে। ট্যাপ করলে, ছবির অস্বচ্ছতা পরিবর্তিত হয় — একটি সহজ উদাহরণ যা ভিউতে জেসচার বাইন্ডিং দেখায়।

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

মূল বিষয়: UIImageView-এ isUserInteractionEnabled ডিফল্টরূপে false — এই ফ্লাগ ছাড়া, Gesture Recognizer স্পর্শ পাবে না। UIView এবং UIButton-এর জন্য, এই ফ্লাগ ডিফল্টরূপে সক্রিয়। অ্যাকশন মেথড UITapGestureRecognizer প্যারামিটার গ্রহণ করে, যার মাধ্যমে ট্যাপ কোঅর্ডিনেট নির্ধারণ করতে location(in:) পাওয়া যায়।

উদাহরণ 2: UISwipeGestureRecognizer — নেভিগেশনের জন্য সোয়াইপ

পূর্ববর্তী স্ক্রিনে ফিরে যেতে বাম সোয়াইপ ইমপ্লিমেন্ট করে। দিক কনফিগারেশন এবং কন্ট্রোলারের রুট ভিউতে জেসচার বাইন্ডিং প্রদর্শন করে।

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 একটি ডিসক্রিট জেসচার: এটি শনাক্তকরণের পরপরই .recognized-এ চলে যায়, কোনো মধ্যবর্তী .changed অবস্থা ছাড়া। তাই, অ্যাকশনে অবস্থা চেক করার প্রয়োজন নেই — জেসচার হয় শনাক্ত হয় (অ্যাকশন ফায়ার হয়) বা না হয়। direction প্রপার্টি চারটি মানের একটি গ্রহণ করে: .left, .right, .up, .down। একাধিক দিক সমর্থনের জন্য, প্রতিটির জন্য আলাদা রিকগনাইজার তৈরি করুন।

উদাহরণ 3: require(toFail:) দিয়ে জেসচার সমন্বয়

দেখায় কিভাবে দ্বন্দ্ব ছাড়া একটি ভিউতে সিঙ্গেল এবং ডাবল ট্যাপ কনফিগার করতে হয়। ডাবল-ট্যাপ রিকগনাইজারের অগ্রাধিকার রয়েছে — সিঙ্গেল ট্যাপ শুধুমাত্র তখনই ফায়ার হয় যদি ডাবল ট্যাপ শনাক্ত না হয়।

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

require(toFail:) ছাড়া, ডাবল ট্যাপে, প্রথমে handleSingleTap ফায়ার হয়, তারপর handleDoubleTap — এটি UX ভেঙে দেয়। require(toFail:) দিয়ে, সিঙ্গেল ট্যাপ ~0.3 সেকেন্ড অপেক্ষা করে যাতে নিশ্চিত হয় দ্বিতীয় ট্যাপ আসছে না। IT Sectr-এ, এই প্যাটার্ন ইমেজ এডিটর এবং গ্যালারিতে ব্যবহৃত হয়, যেখানে ডাবল ট্যাপ জুম করে এবং সিঙ্গেল ট্যাপ একটি এলিমেন্ট নির্বাচন করে।

প্রায়শই জিজ্ঞাসিত প্রশ্ন

একটি ভিউতে কি একাধিক Gesture Recognizer ব্যবহার করা যাবে?

হ্যাঁ, UIView একসঙ্গে একাধিক UIGestureRecognizer ইনস্ট্যান্স সমর্থন করে। দ্বন্দ্ব সমাধানের জন্য, require(toFail:) মেথড ব্যবহার করুন যা শনাক্তকরণ ক্রম নির্ধারণ করে। সমান্তরাল জেসচার অপারেশনের জন্য (যেমন, ম্যাপে pan + pinch), gestureRecognizer(_:shouldRecognizeSimultaneouslyWith:) ডেলিগেট মেথড true রিটার্ন করে ইমপ্লিমেন্ট করুন।

UIGestureRecognizer touchesBegan থেকে কীভাবে আলাদা?

UIGestureRecognizer একটি উচ্চ-স্তরের অ্যাবস্ট্রাকশন যা স্বয়ংক্রিয়ভাবে স্পর্শ প্যাটার্ন শনাক্ত করে এবং অবস্থা পরিচালনা করে। touchesBegan হল UIResponder-এর একটি নিম্ন-স্তরের মেথড যাতে ম্যানুয়াল কোঅর্ডিনেট ট্র্যাকিং, সময় নির্ধারণ এবং স্পর্শ বাতিলের প্রয়োজন হয়। Gesture Recognizer সরল, আরও নির্ভরযোগ্য এবং মানক জেসচারের জন্য পছন্দনীয়; touchesBegan শুধুমাত্র কাস্টম গ্রাফিক্সের জন্য যুক্তিযুক্ত।

Gesture Recognizer কি SwiftUI-তে কাজ করে?

নেটিভ SwiftUI মডিফায়ার ব্যবহার করে: onTapGesture, onLongPressGesture, DragGesture, MagnificationGesture, RotationGesture। এগুলি SwiftUI হায়ারার্কিতে একীভূত UIGestureRecognizer-এর ডিক্লারেটিভ অ্যানালগ। প্রয়োজন হলে, UIViewRepresentable-এর মাধ্যমে UIKit রিকগনাইজার মোড়ানো যায়, কিন্তু Apple নেটিভ SwiftUI জেসচার ব্যবহারের পরামর্শ দেয়।

সারসংক্ষেপ

  • UIGestureRecognizer হল স্বয়ংক্রিয় অবস্থা পরিচালনার সাথে জেসচার শনাক্তকরণ লজিককে পৃথক অবজেক্টে বিভক্ত করার জন্য UIKit-এর একটি অ্যাবস্ট্রাকশন।
  • 7টি বিল্ট-ইন সাবক্লাস 95% সাধারণ জেসচার কভার করে: ট্যাপ, সোয়াইপ, প্যান, পিঞ্চ, রোটেশন, লং প্রেস এবং এজ সোয়াইপ।
  • প্রতিটি রিকগনাইজার 7টি অবস্থার মধ্য দিয়ে যায় — .possible থেকে .ended/.failed পর্যন্ত, যা ডিসক্রিট এবং কন্টিনিউয়াস জেসচারের সঠিক ট্র্যাকিং সক্ষম করে।
  • require(toFail:) মেথড শনাক্তকরণ অগ্রাধিকার নির্ধারণ করে একটি ভিউতে জেসচারের মধ্যে দ্বন্দ্ব সমাধান করে।
  • SwiftUI ডিক্লারেটিভ জেসচার মডিফায়ার ব্যবহার করে, কিন্তু UIKit রিকগনাইজার UIViewRepresentable-এর মাধ্যমে উপলব্ধ।
  • Gesture Recognizer UIKit প্রকল্পের জন্য বাধ্যতামূলক; touchesBegan শুধুমাত্র কাস্টম ড্রইং এবং নিম্ন-স্তরের গ্রাফিক্সের জন্য যুক্তিযুক্ত।
  • ট্যাপ/ডাবল-ট্যাপ জোড়ার জন্য require(toFail:) এবং সমান্তরাল জেসচারের জন্য gestureRecognizer(_:shouldRecognizeSimultaneouslyWith:) ব্যবহার করুন।

আমরা একটি মোবাইল অ্যাপ্লিকেশন টার্নকি তৈরি করব

IT Sectr 2017 সাল থেকে স্টার্টআপ এবং ব্যবসার জন্য iOS এবং Android অ্যাপ্লিকেশন তৈরি করে। আমরা আপনাকে পরামর্শ দেব এবং সেরা সমাধান প্রস্তাব করব।

প্রকল্প নিয়ে আলোচনা করুন

আরও পড়ুন