मुख्य बिंदु
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 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 की जाँच करें — यह जेस्चर की शुरुआत, बदलाव और अंत को अलग करने की अनुमति देता है।
UIKit 7 बिल्ट-इन UIGestureRecognizer सबक्लास प्रदान करता है, जो अधिकांश इंटरैक्शन परिदृश्यों को कवर करते हैं। प्रत्येक सबक्लास में विशिष्ट सेटिंग्स होती हैं: टैप के लिए numberOfTapsRequired, स्वाइप के लिए direction, लॉन्ग प्रेस के लिए minimumPressDuration।
कस्टम जेस्चर (जैसे, ज़िगज़ैग बनाना) के लिए, 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:) प्राथमिकताओं के साथ एक जेस्चर स्कीम होती है — इसने डबल-टैप फायरिंग बग्स को पूरी तरह से समाप्त कर दिया।
UIImageView पर एक सिंगल टैप हैंडलर जोड़ता है। टैप करने पर, इमेज की अपारदर्शिता बदल जाती है — एक सरल उदाहरण जो व्यू के साथ जेस्चर बाइंडिंग दिखाता है।
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:) प्राप्त किया जा सकता है।
पिछली स्क्रीन पर वापस जाने के लिए लेफ्ट स्वाइप लागू करता है। दिशा कॉन्फ़िगरेशन और कंट्रोलर की रूट व्यू में जेस्चर बाइंडिंग प्रदर्शित करता है।
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। कई दिशाओं का समर्थन करने के लिए, प्रत्येक के लिए अलग-अलग रिकॉग्नाइज़र बनाएँ।
दिखाता है कि बिना विरोध के एक व्यू पर सिंगल और डबल टैप कैसे कॉन्फ़िगर करें। डबल-टैप रिकॉग्नाइज़र की प्राथमिकता है — सिंगल टैप तभी फायर होता है जब डबल टैप पहचाना न जाए।
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 में, यह पैटर्न इमेज एडिटर और गैलरी में उपयोग किया जाता है, जहाँ डबल टैप ज़ूम करता है और सिंगल टैप एक एलिमेंट का चयन करता है।
अक्सर पूछे जाने वाले प्रश्न
हाँ, UIView एक साथ कई UIGestureRecognizer इंस्टेंस का समर्थन करता है। विरोधों को हल करने के लिए, require(toFail:) मेथड का उपयोग करें जो पहचान क्रम निर्धारित करता है। समानांतर जेस्चर संचालन (जैसे, मैप पर pan + pinch) के लिए, true लौटाने वाली gestureRecognizer(_:shouldRecognizeSimultaneouslyWith:) डेलिगेट मेथड लागू करें।
UIGestureRecognizer एक उच्च-स्तरीय एब्स्ट्रैक्शन है जो स्वचालित रूप से स्पर्श पैटर्न पहचानता है और स्थितियों का प्रबंधन करता है। touchesBegan एक निम्न-स्तरीय UIResponder मेथड है जिसमें मैन्युअल कोऑर्डिनेट ट्रैकिंग, टाइमिंग और स्पर्श रद्दीकरण की आवश्यकता होती है। Gesture Recognizer सरल, अधिक विश्वसनीय और मानक जेस्चर के लिए बेहतर है; touchesBegan केवल कस्टम ग्राफ़िक्स के लिए उचित है।
नेटिव SwiftUI मॉडिफ़ायर का उपयोग करता है: onTapGesture, onLongPressGesture, DragGesture, MagnificationGesture, RotationGesture। ये SwiftUI पदानुक्रम में एकीकृत UIGestureRecognizer के डिक्लेरेटिव एनालॉग हैं। यदि आवश्यक हो, तो UIViewRepresentable के माध्यम से UIKit रिकॉग्नाइज़र को लपेटा जा सकता है, लेकिन Apple नेटिव SwiftUI जेस्चर का उपयोग करने की सलाह देता है।
सारांश
हम एक मोबाइल एप्लिकेशन टर्नकी विकसित करेंगे
IT Sectr 2017 से स्टार्टअप और व्यवसायों के लिए iOS और Android एप्लिकेशन बनाता है। हम आपको सलाह देंगे और सर्वोत्तम समाधान प्रस्तावित करेंगे।
यह भी पढ़ें