UITapGestureRecognizer - सिंगल टैप और डबल टैप


156

मैं 2 जोड़ने की कोशिश कर रहा हूं UITapGestureRecognizers एक दृश्य में , एक सिंगल टैप के लिए और एक डबल टैप इवेंट के लिए। एकल टैप पहचानकर्ता अपेक्षित (अपने दम पर) के रूप में काम कर रहा है। लेकिन मुझे लगता है कि डबल टैप पहचानकर्ता काम करने में सक्षम नहीं है।

जैसे गुणों के साथ प्रयोग करने के लिए करने की कोशिश की: cancelsTouchesInView, delaysTouchesBeganऔर delaysTouchesEnded, लेकिन अभी भी काम नहीं करता है।

जब मैं डबल टैप करता हूं, तो सिंगल टैप पहचानकर्ता हमेशा सक्रिय हो जाएगा और डबल टैप इवेंट को सुपर व्यू में भी भेजा जाएगा। लेकिन कस्टम डबल टैप पहचानकर्ता को बिल्कुल भी सूचित नहीं किया जाता है।

दस्तावेज़ों से प्रतीत होता है कि उपर्युक्त 3 गुणों का उपयोग इस उद्देश्य के लिए किया जा सकता है। लेकिन मुझे यकीन नहीं है कि किन मूल्यों को निर्धारित किया जाना चाहिए और किस पर पहचानकर्ता (ओं), (एकल, डबल या दोनों)। आशा है कि इससे परिचित कोई व्यक्ति मदद कर सकता है।

निम्नलिखित नवीनतम अद्यतन कोड ब्लॉक है।

// ****** gesture recognizers ******

- (void)addSingleAndDoubleTapGestureRecognizersToView:(UIView *)view
{
    // single tap    
    UITapGestureRecognizer *singleTapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget: tableViewController action: @selector(handleSingleTapOnView:)];                                 
    [singleTapRecognizer setNumberOfTouchesRequired:1];
    [view addGestureRecognizer: singleTapRecognizer];

    // double tap 
    UITapGestureRecognizer *doubleTapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget: tableViewController action: @selector (handleDoubleTapOnView:)];        
    [doubleTapRecognizer setNumberOfTouchesRequired:2];         
    [singleTapRecognizer requireGestureRecognizerToFail: doubleTapRecognizer];
    [view addGestureRecognizer: doubleTapRecognizer];         
}

- (void)handleSingleTapOnView:(id)sender
{

}

- (void)handleDoubleTapOnView:(id)sender
{

}

30
यादृच्छिक टिप्पणी: चर नामों में अंडरस्कोर सबसे अधिक उद्देश्य-सी प्रोग्रामर को कमज़ोर बना देगा। क्या बुरा है कि आपके चर नाम वर्णनात्मक नहीं हैं। सिर्फ सिंगलटैप रिकॉग्नाइजर और डबलटैप रिक्राइजर (या कुछ इसी तरह) का उपयोग क्यों नहीं किया जाता है? यह टाइप करने के लिए दूसरा विभाजन लेता है, लेकिन आपके कोड को असीम रूप से अधिक पठनीय बनाता है।
UIAdam

सलाह के लिए धन्यवाद, आपसे सहमत हैं कि चर नाम अधिक वर्णनात्मक होना चाहिए। लेकिन इस विशेष कोड सेगमेंट को अंतिम रूप नहीं दिया गया है और सुझाव के अनुसार अधिक पॉलिश और वर्णनात्मक कोड पोस्ट किया जाएगा ...
स्टेनली

मामले में किसी और को भी इसी तरह की समस्या है। मैंने डबल टैप और सिंगल टैप पहचानकर्ताओं को स्विफ्ट में एक साथ काम करने के लिए संघर्ष किया (सिंगल टैप ठीक काम कर रहा था, लेकिन कोई डबल टैप नहीं)। मैंने स्टोरीबोर्ड का उपयोग करके पहचानकर्ताओं को दृश्य पर खींच लिया। मेरे पास हैंडलर और स्टेटमेंट था: singleTapRecognizer.requireGestureRecognizerToFail (doubleTabRecognizer) मेरे viewDidLoad के अंदर, लेकिन फिर भी कोई डबल टैप नहीं। पहेली का मेरा अनुपलब्ध टुकड़ा डबल टैप पहचानकर्ता आइकन (दृश्य की शीर्ष पंक्ति से) को उस दृश्य के हिस्से पर खींचना था जहां डबल टैप को पहचाना जाना था।
पॉलस

1
@ यूआईएडीएमएआरसी में एक निजी आइवर नाम को उपसर्ग करने के लिए अंडरस्कोर का उपयोग करना काफी सामान्य है, हालांकि नहीं? (एक तेज पृष्ठभूमि से आ रहा है)
चार्लटन प्रोवाटास

जवाबों:


412
UITapGestureRecognizer *singleTap = [[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(doSingleTap)] autorelease];
singleTap.numberOfTapsRequired = 1; 
[self.view addGestureRecognizer:singleTap];

UITapGestureRecognizer *doubleTap = [[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(doDoubleTap)] autorelease];
doubleTap.numberOfTapsRequired = 2; 
[self.view addGestureRecognizer:doubleTap];

[singleTap requireGestureRecognizerToFail:doubleTap];

नोट: यदि आप इसका उपयोग कर रहे हैं तो numberOfTouchesRequired यह होना चाहिए .numberOfTouchesRequired = 1;

स्विफ्ट के लिए

let singleTapGesture = UITapGestureRecognizer(target: self, action: #selector(didPressPartButton))
singleTapGesture.numberOfTapsRequired = 1
view.addGestureRecognizer(singleTapGesture)

let doubleTapGesture = UITapGestureRecognizer(target: self, action: #selector(didDoubleTap))
doubleTapGesture.numberOfTapsRequired = 2
view.addGestureRecognizer(doubleTapGesture)

singleTapGesture.require(toFail: doubleTapGesture)

उत्तर के लिए धन्यवाद, अपने कोड की कोशिश की है, लेकिन यह अभी भी काम नहीं कर रहा है। वहाँ अभी भी कुछ मुझे याद किया जाना चाहिए था। क्या आपके पास कोई और संकेत है?
स्टेनली

क्या मुझे इसके लिए आपकी कार्यान्वयन फ़ाइल मिल सकती है?
अनिल कोठारी

@ स्टेनली: अनिल का जवाब काम करना चाहिए, बेशक आपको हैंडलर भी उपलब्ध कराना है (doSingleTap, doDoubleTap)
Rok Jarc

एकल टैप UITableView को अपडेट करता है जो अपेक्षित रूप से काम कर रहा है। डबल टैप, फिलहाल, केवल NSLog का उपयोग करके लॉग स्टेटमेंट को आउटपुट करता है। मेरा संदेह यह है कि पहली प्रतिक्रिया स्थिति UIView से पहले टैप के बाद कहीं और जाती है क्योंकि मैंने प्रतिक्रिया श्रृंखला के बारे में स्पष्ट रूप से कुछ भी नहीं किया है।
स्टैनले

6
समाधान मेरे लिए काम करता है। सिंगल टैप चयनकर्ता को कुछ देरी के बाद निकाल दिया जाता है।
व्लादिमीर ओबरीज़ान

46

स्विफ्ट 3 समाधान:

let singleTap = UITapGestureRecognizer(target: self, action:#selector(self.singleTapAction(_:)))
singleTap.numberOfTapsRequired = 1
view.addGestureRecognizer(singleTap)

let doubleTap = UITapGestureRecognizer(target: self, action:#selector(self.doubleTapAction(_:)))
doubleTap.numberOfTapsRequired = 2
view.addGestureRecognizer(doubleTap)

singleTap.require(toFail: doubleTap)

कोड लाइन singleTap.require (toFail: doubleTap) में हम यह सुनिश्चित करने के लिए कि टैप इवेंट एक डबल टैप नहीं है, यह सुनिश्चित करने के लिए हम मजबूर कर रहे हैं।


31

आपको आवश्यकता का उपयोग करने की आवश्यकता हैGestureRecognizerToFail: विधि। कुछ इस तरह:

[singleTapRecognizer requireGestureRecognizerToFail:doubleTapRecognizer];


दोनों पहचानकर्ताओं के साथ "फ़ेल" पद्धति कॉल का उपयोग करने की कोशिश की है। लेकिन फिर भी काम नहीं करता है। यदि आपको पहले काम करने के लिए डबल टैप चीज़ मिल गई है, तो कृपया अपना कुछ और अनुभव मेरे साथ साझा करें।
स्टेनली

1
मैंने इस सटीक कोड की कोशिश की है (जैसा कि अनिल ने और अधिक विस्तार से पोस्ट किया है) और यह मेरे लिए काम करता है।
UIAdam

टिप्पणी के लिए धन्यवाद, फिर भी कुछ ऐसा होना चाहिए जो मुझे अपनी ओर से याद आए ...
स्टेनली

आपका कोड अभी भी डेलटचॉट और व्हाट्सएप के साथ गड़बड़ करता है। इसे ऐसा बनाएं कि यह अनिल के कोड का ठीक-ठीक अनुसरण करे। जिस तरह से हमारे पास है, केवल एक बार आवश्यकताGestureRecognizerToFail का उपयोग करें।
UIAdam

जैसा कि आपने आज या कल बाद में सलाह दी है, वैसे ही मैं इस समय के लिए बाहर चला रहा हूं। अपनी तरह की सहायता के लिए धन्यवाद ...
स्टेनली

15

// ---- सबसे पहले आपको डबल और सिंगल टैप जेस्चर आवंटित करना होगा ------- //

UITapGestureRecognizer* doubleTap = [[UITapGestureRecognizer alloc] initWithTarget : self action : @selector (handleDoubleTap:)];

UITapGestureRecognizer* singleTap = [[UITapGestureRecognizer alloc] initWithTarget : self action : @selector (handleSingleTap:)];

[singleTap requireGestureRecognizerToFail : doubleTap];
[doubleTap setDelaysTouchesBegan : YES];
[singleTap setDelaysTouchesBegan : YES];

// ----------------------- नल की संख्या ---------------- //

[doubleTap setNumberOfTapsRequired : 2];
[singleTap setNumberOfTapsRequired : 1];

// ------- दृश्य या बटन पर डबल टैप और सिंगल टैप जेस्चर जोड़ें -------- //

[self.view addGestureRecognizer : doubleTap];
[self.view addGestureRecognizer : singleTap];

10

निश्चित नहीं है कि यदि आप वास्तव में क्या देख रहे हैं, लेकिन मैंने इशारों को पहचानने वालों के बिना सिंगल / डबल टैप किया। मैं इसे यूआईटेबल व्यू में उपयोग कर रहा हूं, इसलिए मैंने उस कोड का इस्तेमाल कियाSelectRowAtIndexPath विधि में

    tapCount++;
    switch (tapCount)
    {
        case 1: //single tap
            [self performSelector:@selector(singleTap:) withObject: indexPath afterDelay: 0.2];
            break;
        case 2: //double tap
            [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(singleTap:) object:indexPath];
            [self performSelector:@selector(doubleTap:) withObject: indexPath];
            break;
        default:
            break;
    }
    if (tapCount>2) tapCount=0;

सिंगलटैप और डबलटैप केवल एक पैरामीटर के रूप में NSIndexPath के साथ शून्य हैं:

- (void)singleTap:(NSIndexPath *)indexPath {
  //do your stuff for a single tap
}

- (void)doubleTap:(NSIndexPath *)indexPath {
  //do your stuff for a double tap
}

आशा करता हूँ की ये काम करेगा


उत्तर के लिए धन्यवाद, @ नोवार्ग। क्या आपको डबलटैप पहचानकर्ताओं के बारे में समस्या है?
स्टेनली

@ स्टैनले नोप, सिंगलटैप फायरिंग से 0.2 सेकंड पहले प्रतीक्षा कर रहा है। और अगर इस बीच में दूसरा नल सक्रिय हो गया, तो सिंगलटैप पद्धति रद्द हो जाती है।
नवार्ग

यह बहुत ही आशाजनक लग रहा है, आपकी सहायता के लिए धन्यवाद। आज फिर से बाहर चल रहा हूँ। निश्चित रूप से इसे कल आजमाएंगे :)
स्टेनली

रचनात्मक उत्तर;)
माइकल

बहुत अच्छा समाधान। मुझे केवल प्रत्येक हैंडलर (सिंगलटैप, डबलटैप) पर टैपकाउंट = 0 जोड़ने की जरूरत है ताकि यह सुनिश्चित हो सके कि निम्नलिखित टच को भी पहचाना जाए।
Sirio

3

2 स्विफ्ट के लिए समाधान:

let singleTapGesture = UITapGestureRecognizer(target: self, action: #selector(handleSingleTap))
singleTapGesture.numberOfTapsRequired = 1 // Optional for single tap
view.addGestureRecognizer(singleTapGesture)

let doubleTapGesture = UITapGestureRecognizer(target: self, action: #selector(handleDoubleTap))
doubleTapGesture.numberOfTapsRequired = 2
view.addGestureRecognizer(doubleTapGesture)

singleTapGesture.requireGestureRecognizerToFail(doubleTapGesture)

1

मैंने UIGestureRecognizerDelegate के तरीकों को लागू किया ताकि सिंगलटैप और डबलटैप दोनों का पता लगाया जा सके।

बस यह करो।

 UITapGestureRecognizer *doubleTap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(handleDoubleTapGesture:)];
    [doubleTap setDelegate:self];
    doubleTap.numberOfTapsRequired = 2;
    [self.headerView addGestureRecognizer:doubleTap];

    UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(handleSingleTapGesture:)];
    singleTap.numberOfTapsRequired = 1;
    [singleTap setDelegate:self];
    [doubleTap setDelaysTouchesBegan:YES];
    [singleTap setDelaysTouchesBegan:YES];
    [singleTap requireGestureRecognizerToFail:doubleTap];
    [self.headerView addGestureRecognizer:singleTap];

फिर इन प्रतिनिधि विधियों को लागू करें।

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch{
    return  YES;
}

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer{
    return YES;
}

0

कुछ दृश्य में स्वयं के डबल टैप पहचानकर्ता बने होते हैं ( MKMapViewउदाहरण के तौर पर)। इसके आस-पास जाने के लिए आपको UIGestureRecognizerDelegateविधि लागू करने shouldRecognizeSimultaneouslyWithGestureRecognizerऔर लौटने की आवश्यकता होगी YES:

पहले अपने दोहरे और एकल पहचानकर्ताओं को लागू करें:

// setup gesture recognizers
UITapGestureRecognizer* singleTapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self
                                                                                action:@selector(mapViewTapped:)];
singleTapRecognizer.delegate = self;
singleTapRecognizer.numberOfTapsRequired = 1;


UITapGestureRecognizer* doubleTapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self
                                                                                      action:@selector(mapViewDoubleTapped:)];
doubleTapRecognizer.delegate = self;    // this allows
doubleTapRecognizer.numberOfTapsRequired = 2;
[singleTapRecognizer requireGestureRecognizerToFail:doubleTapRecognizer];

और फिर लागू करें:

#pragma mark UIGestureRecognizerDelegate
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer
*)otherGestureRecognizer {  return YES; }

-1

@ स्टेनले की टिप्पणी के संदर्भ में -

कोशिश मत करो और काम करने के लिए पंक्ति चयन के लिए नल इशारों का उपयोग करें UITableViewक्योंकि इसमें पहले से ही पूर्ण नल हैंडलिंग है ...।

लेकिन आपको अपने एकल टैप जेस्चर पहचानकर्ताओं पर 'NO' को 'View' में सेट करना होगा या इसे टैप ईवेंट नहीं मिलेंगे।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.