क्या आप कई विचारों के लिए एक UIGestureRecognizer संलग्न कर सकते हैं?


228
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapTapTap:)];
[self.view1 addGestureRecognizer:tapGesture];
[self.view2 addGestureRecognizer:tapGesture];
[tapGesture release];

उपरोक्त कोड में केवल टैप पर view2ही मान्यता प्राप्त है। अगर मैं तीसरी पंक्ति पर टिप्पणी करता हूं तो नल view1को मान्यता दी जाती है। अगर मैं सही हूं और आप केवल एक बार जेस्चर पहचानकर्ता का उपयोग कर सकते हैं, तो मुझे यकीन नहीं है कि यह बग है या इसे सिर्फ कुछ और प्रलेखन की आवश्यकता है।

जवाबों:


334

A UIGestureRecognizerका उपयोग एकल दृश्य के साथ किया जाना है। मैं मानता हूं कि प्रलेखन धब्बेदार है। यह UIGestureRecognizerएक एकल viewसंपत्ति इसे दूर देता है:

राय

इशारा पहचानकर्ता से जुड़ा हुआ है। (सिफ़ पढ़िये)

@property (गैर-परमाणु, आसानी से) UIView * दृश्य

चर्चा आप AddGestureRecognizer: विधि का उपयोग करके एक UIView ऑब्जेक्ट के लिए एक इशारा पहचानकर्ता (या जोड़) देते हैं।


11
क्योंकि एक इशारा पहचानकर्ता को एक दृश्य में जोड़ना रनटाइम (बनाम संकलन समय) पर होता है।
टॉमस्विफ्ट

1
मुझे वह मिल गया, लेकिन यह कहना कि हमने चर का उपयोग नहीं किया है, एक्सकोड कोड के आधार पर बता सकता है कि हमने एक ही पहचानकर्ता को कई बार देखा है और कोडर को चेतावनी दे सकता है।
ज़ोल्टन मटुक

1
समान यूआईटीएपग्रेचर रिकॉगनाइज़र को असाइन करने के लिए कई विचारों के बारे में संकलक चेतावनी बकवास है, क्योंकि आप उद्देश्य पर ऐसा करना चाह सकते हैं, उदाहरण के लिए यदि आप नल इशारा पहचानकर्ता को एक दृश्य से दूसरे स्थान पर ले जाना चाहते हैं। उस ने कहा, यह एक मूर्खतापूर्ण सीमा है कि इशारा पहचानकर्ता का उपयोग कई विचारों पर नहीं किया जा सकता है।
एरिक वैन डेर नीट

1
iOS 9 अब प्रति हावभाव पहचानकर्ता के लिए एक एकल दृश्य को लागू करता है, मैं नीचे इंटरफ़ेस बिल्डर विधि का उपयोग कर रहा हूं, लेकिन अब मुझे निम्न संदेश मिलता है जब मैं इसका उपयोग करने का प्रयास करता हूं (संक्षिप्तता के लिए कुछ विवरण कटे हुए): चेतावनी: एक पहचानकर्ता पहचानकर्ता (< UITapGestureRecognizer: .....>) एक स्टोरीबोर्ड / xib में एक से अधिक दृश्य में जोड़े जाने के लिए सेटअप किया गया था (-> <UIView:; फ्रेम = (0 44; 600 536); ऑटोरेसेज़ = RM + बीएम; जेस्चर-पहचानकर्ता = <; NSArray ...:>; परत = <CALayer: ... >>) एक समय में, यह कभी भी अनुमति नहीं थी, और अब इसे लागू किया गया है। IOS 9.0 के साथ शुरुआत करते हुए इसे पहले दृश्य में लोड किया जाएगा।
जॉर्ज ब्राउन

यदि आप दूसरी बार देखने के लिए जोड़ रहे हैं, तो इससे पहले दृश्य संलग्न किया गया था कि इस पहचानकर्ता द्वारा स्वचालित रूप से अनासक्त हो रहा है UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(didPressed:)]; [self.view1 addGestureRecognizer:tapRecognizer]; [self.view2 addGestureRecognizer:tapRecognizer];आउटपुट view1 में कोई इशारा पहचानकर्ता सरणी नहीं है; व्यू 2 को जेस्चर पहचानकर्ता सरणी मिली है
kokos8998

48

मैं नीचे का उपयोग करके इसके चारों ओर मिला।

for (UIButton *aButton in myButtons) {

            UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleLongPress:)];
            longPress.minimumPressDuration=1.0;
            [aButton addGestureRecognizer:longPress];
            [longPress release];

}

फिर मेरे हैंडल लॉन्गप्रेस विधि में मैंने इशारे पहचानकर्ता और शाखा के दृश्य के बराबर एक यूआईब्यूटॉन स्थापित किया है जो मैं उस बटन पर आधारित करता हूं

- (void)handleLongPress:(UILongPressGestureRecognizer*)gesture {
    if ( gesture.state == UIGestureRecognizerStateEnded ) {
        UIButton *whichButton=(UIButton *)[gesture view];
        selectedButton=(UIButton *)[gesture view];
    ....
}

1
महान जवाब। धन्यवाद एक टन। यह स्वीकृत उत्तर हो सकता था यदि प्रश्न "आप कई विचारों के लिए एक UIGestureRecognizer कैसे संलग्न करें?"
D_D

7
यह (या इसके बहुत करीब कुछ) मेरे काम नहीं आया। मैंने इंटरफ़ेस बिल्डर में एक टैप जेस्चर पहचानकर्ता में कई विचार जोड़े, और पहचानकर्ता को एक क्रिया से जोड़ा। कार्रवाई को कभी भी संलग्न दृश्य के रूप में कहा जाता था, लेकिन इशारे.व्यू हमेशा अंतिम दृश्य जुड़ा हुआ था।
अनिल मल्लावरपु

यह वास्तव में अच्छा जवाब है और वास्तव में सहायक भी है और @MicRO +1
दिलीप

2
Aneil, ऐसा इसलिए है क्योंकि आपने जेस्चर पहचानकर्ता के नए उदाहरण नहीं बनाए हैं। इस उत्तर में लूप में जो हो रहा है वह यह है कि जेस्चर पहचानकर्ताओं के नए उदाहरण बनाए गए हैं, प्रत्येक में केवल एक दृश्य जुड़ा हुआ है। वे सभी एक ही हैंडलर की ओर इशारा कर सकते हैं, जहाँ आप तब देखने के लिए जाँच करें कि कौन सा स्पर्श किया गया था।
एरिक वैन डेर नीट

1
क्या कोई और पुष्टि कर सकता है कि यह अब ओब्ज-सी / स्विफ्ट के वर्तमान संस्करण में काम नहीं करता है?
मैक्सी मुस

18

स्विफ्ट 3 के मामले में किसी को भी इसकी आवश्यकता होती है: उपर्युक्त भाविक राठौड़ उत्तर के आधार पर।

 func setGestureRecognizer() -> UIPanGestureRecognizer {

        var panRecognizer = UIPanGestureRecognizer()

        panRecognizer = UIPanGestureRecognizer (target: self, action: #selector(pan(panGesture:)))
        panRecognizer.minimumNumberOfTouches = 1
        panRecognizer.maximumNumberOfTouches = 1
        return panRecognizer
    }

        ///set the recognize in multiple views
        view1.addGestureRecognizer(setGestureRecognizer())
        view2.addGestureRecognizer(setGestureRecognizer())

3
यह मूल रूप से दो विचारों के लिए कई इशारों का निर्माण कर रहा है, अभी भी एक ही नियम है: हर हावभाव में केवल एक ही दृश्य जुड़ा हुआ है
Abdoelrhman

3
नहीं, फ़ंक्शन हर बार जब यह कहा जाता है, तो एक इशारा
बनाता है

2
फ़ंक्शन का नाम गलत है। तार्किक समारोह यहाँ एक कार्य हो रहा है। इसलिए इसका नामकरण किया जाना चाहिए: getGestureRecognizeक्योंकि यही वह कार्य करता है
डेविड सीक

मेरे लिए अच्छा काम करो! और कई चर बनाने की तुलना में अधिक साफ कोड या addGestureRecognizer के अंदर निर्माण के लिए पूरे कोड डाल
Codenator81

11

हम ऐसा कुछ कर सकते हैं, यह आसान और सरल है

1) अपने नियंत्रक में नीचे के रूप में फ़ंक्शन बनाएं (यह फ़ंक्शन GestureRecognizer वापस आ जाएगा)

-(UITapGestureRecognizer*)setRecognizer{
     UITapGestureRecognizer *gestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(openProfile)];
     [gestureRecognizer setNumberOfTapsRequired:1];
     return gestureRecognizer;
}

2) अब इस पहचानकर्ता को कई दृश्यों में सेट करें

[self.view1 addGestureRecognizer:[self setRecognizer]]; 
[self.view2 addGestureRecognizer:[self setRecognizer]];

यह मेरे लिए काम नहीं कर रहा है जब मैं विचारों के बजाय दो लेबल का उपयोग करता हूं।
मिहिर ओझा

3
@ मिहिर ओझा, यह सीधे यूआईएलबेल्स के लिए काम नहीं कर सकता है। लेबल की वजह से उपयोगकर्ता इंटरैक्शन के लिए समझ में नहीं आता है। अगर आप UILabels के लिए इशारों को जोड़ना चाहते हैं तो स्विफ्ट में इस सिंगल लाइन लेबलनाम को जोड़ें..इसेसेटरइंटरनेशन सक्षम किया गया है। फिर इशारे जोड़ें।
iOS

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

1
मुझे लगता है कि लाइन setNumberOfTapsRequired:1आवश्यक नहीं है
नवेद अब्बास

9

नहीं, आपको एक से अधिक दृश्यों के लिए जेस्चर पहचानकर्ताओं को संलग्न नहीं करना चाहिए।

Apple प्रलेखन में यह स्पष्ट जानकारी है:

इशारा पहचानने वाले एक दृश्य से जुड़े होते हैं

हर हावभाव पहचानकर्ता एक दृश्य के साथ जुड़ा हुआ है। इसके विपरीत, एक दृश्य में कई हावभाव पहचानकर्ता हो सकते हैं, क्योंकि एक ही दृश्य कई अलग-अलग इशारों का जवाब दे सकता है। किसी विशेष दृश्य में होने वाले स्पर्शों को पहचानने के लिए जेस्चर पहचानकर्ता के लिए, आपको उस दृश्य के लिए जेस्चर पहचानकर्ता को संलग्न करना होगा।

IOS के लिए ईवेंट हैंडलिंग गाइड - जेस्चर रिक्रूटर्स ऐप्पल डेवलपर लाइब्रेरी

जबकि अन्य लोगों का उल्लेख है कि वे कुछ मामलों में काम कर सकते हैं यह स्पष्ट रूप से प्रलेखन के खिलाफ है और भविष्य के किसी भी आईओएस संस्करण में बदल सकता है।

आप क्या कर सकते हैं अलग-अलग जेस्चर पहचानकर्ताओं को उन विचारों में जोड़ सकते हैं जिन्हें आप मॉनिटर करना चाहते हैं और वे एक सामान्य कार्रवाई साझा कर सकते हैं।


4

यदि कोई व्यक्ति कई बटन के लिए इशारा दृश्य जोड़ने के लिए कोड नहीं करना चाहता है, जैसे कि kwalker ने ऊपर उत्तर दिया है, और इसे इंटरफ़ेस बिल्डर के माध्यम से करना चाहते हैं तो यह आपकी मदद कर सकता है।

1) आप ऑब्जेक्ट लाइब्रेरी से लॉन्ग प्रेस जेस्चर रिकॉगनाइजर जोड़ सकते हैं जैसे आप यूआईबटन और यूआईबेल्स जैसी अन्य वस्तुओं को जोड़ते हैं।

यहां छवि विवरण दर्ज करें प्रारंभ में मैंने जो प्रयोग किया था, वह केवल एक ही था

2) UIButtonफ़ाइल के मालिक के साथ संदर्भित दुकानों को भेजा और कार्रवाई की।

यहां छवि विवरण दर्ज करें

नोट: यदि आपके पास कई UIButton या कोई अन्य ऑब्जेक्ट है, तो आपको उनमें से प्रत्येक के लिए अलग जेस्चर पहचानकर्ता की आवश्यकता होगी। अधिक जानकारी के लिए कृपया मेरे इस प्रश्न का संदर्भ लें। लॉन्ग प्रेस जेस्चर पहचानकर्ता पर गलत यूआईबटन टैग प्राप्त करना


IB का उपयोग करके एक से अधिक UIView को पहचानने वाले को बांधना बहुत आसान है। सवाल कोड जनरेशन को लेकर था।
AlexeyVMP

3

अगर आपने तय किया है कि मैं आपको कुछ ऐसा करने का सुझाव देता हूं

[self.view1 addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapTapTap:)]];
[self.view2 addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapTapTap:)]];

इस तरह से कई अलग-अलग बेकार चर कम हो जाएंगे


3

आप आसानी से जेस्चर पहचानकर्ताओं को जोड़ने के लिए दृश्य पर एक सामान्य एक्सटेंशन बना सकते हैं। यह सिर्फ एक उदाहरण है लेकिन यह इस तरह दिख सकता है

extension UIView {

    func setGestureRecognizer<Gesture: UIGestureRecognizer>(of type: Gesture.Type, target: Any, actionSelector: Selector, swipeDirection: UISwipeGestureRecognizer.Direction? = nil, numOfTaps: Int = 1) {
    let getRecognizer = type.init(target: target, action: actionSelector)

    switch getRecognizer {
    case let swipeGesture as UISwipeGestureRecognizer:
        guard let direction = swipeDirection else { return }
        swipeGesture.direction = direction
        self.addGestureRecognizer(swipeGesture)
    case let tapGesture as UITapGestureRecognizer:
        tapGesture.numberOfTapsRequired = numOfTaps
        self.addGestureRecognizer(tapGesture)
    default:
        self.addGestureRecognizer(getRecognizer)
    }
  }

}

एक कॉल पर 2 टैप पहचानकर्ता जोड़ने के लिए आप बस कॉल करेंगे:

let actionSelector = #selector(actionToExecute)
view.setGestureRecognizer(of: UITapGestureRecognizer.self, target: self, actionSelector: actionSelector, numOfTaps: 2)

आप आसानी से एक स्वाइप पहचानकर्ता भी जोड़ सकते हैं

view.setGestureRecognizer(of: UISwipeGestureRecognizer.self, target: self, actionSelector: actionSelector, swipeDirection: .down)

और इसी तरह। बस याद रखें कि लक्ष्य चयनकर्ता से जुड़ा होना चाहिए।


2

' <UIScrollViewDelegate>' द्वारा वर्ग को ओवरराइड करें

और इस विधि का उपयोग करें।

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

यह विधि आपको एक दृश्य पर कई स्वाइप सक्षम करने में मदद करेगी ।।


2

हर बार जब आप एक इशारे से इशारा करने वाले एक इशारे को पहचानने वाले को जोड़ते हैं, तो हर बार अपने GestureRecognize को दोबारा लिखें (रीक्रिएट करें) के बारे में क्या। नीचे मामले में यह काम करता है। मैं IBOutletCollection का उपयोग कर रहा हूं

स्विफ्ट 2:

@IBOutlet var topicView: [UIView]!

override func viewDidLoad() {
        for view in self.topicView as [UIView] {
        view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: "viewClicked:"))
    }
}

func viewClicked(recognizer: UITapGestureRecognizer) {
    print("tap")
}

-6

आप इसे इस कोड का उपयोग करके कर सकते हैं मेरे विचार जो xib में इमेजव्यू हैं।

- (void)viewDidLoad
{
    firstIV.tag = 501;
    secondIV.tag = 502;
    thirdIV.tag = 503;
    forthIV.tag = 504;

    [self addTapGesturetoImageView: firstIV];
    [self addTapGesturetoImageView: secondIV];
    [self addTapGesturetoImageView: thirdIV];
    [self addTapGesturetoImageView: forthIV];
}

-(void)addTapGesturetoImageView:(UIImageView*)iv
{
    iv.userInteractionEnabled = YES;
    UITapGestureRecognizer * textfielBGIVTapGasture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(textfielBGIVTapped:)];
    textfielBGIVTapGasture.numberOfTapsRequired = 1;
    [iv addGestureRecognizer:textfielBGIVTapGasture];
}

- (void)textfielBGIVTapped:(UITapGestureRecognizer *)recognizer {
    int tag = recognizer.view.tag-500;
    switch (tag) {
        case 1:
        {
            //firstIV tapped;
            break;
        }
        case 2:
        {
            //secondIV tapped;
            break;
        }
        case 3:
        {
            //thirdIV tapped;
            break;
        }
        case 4:
        {
            //forthIV tapped;
            break;
        }
        default: {
            break;
        }
    }
}

1
आप कई हावभाव पहचानकर्ता बना रहे हैं; मेरा मूल प्रश्न एक एकल इशारा पहचानकर्ता के पुन: उपयोग के बारे में था, जो आप नहीं कर सकते।
22

1
500आपके सभी विचारों के टैग को जोड़ने और फिर घटाने के बारे में क्या कहना है 500? इसके बजाय 1(या यहां तक ​​कि 0) पर अपने टैग क्यों नहीं शुरू करें 501?
15:11 बजे ma11hew28

@MattDiPasquale, इससे कोई फर्क नहीं पड़ता कि आप 1इसकी शुरुआत करना चाहते हैं या नहीं, मैंने इस कोड को अपने ऐप से कॉपी किया है जहां मैं इसे दे रहा हूं 501। लेकिन हाँ दे 0bcoz मैं कहीं पढ़ा है कि इसके हमेशा माता-पिता को देखें तो यह जटिलता पैदा करेगा, मेरा विश्वास करो कि मैंने इसका सामना किया है।
दिलीप

प्रलेखन में मुख्य पाठ "दृश्य इशारा पहचानकर्ता के लिए एक मजबूत संदर्भ स्थापित करता है।" जिसका अर्थ है कि दृश्य इशारे का मालिक है। इशारा केवल एक मालिक का हो सकता है। लिंक
प्रेत ५५
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.