2011-01-07 11 views
35

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

पहली बात मैंने कोशिश की

- (BOOL)touchesShouldCancelInContentView:(UIView *)view 

ओवरराइड करने के लिए था और बस UIScrollView पिकर दृश्य के अंदर अंतिम रूप को रद्द करने की अनुमति नहीं। यह काम करता है, लेकिन यह एक अप्रिय दुष्प्रभाव है। आप पिकर व्यू को तुरंत जवाब देना चाहते हैं और इस प्रकार आपको delaysContentTouches को NO पर सेट करना होगा। समस्या यह है कि आप नहीं चाहते कि शेष तालिका तुरंत प्रतिक्रिया दे, क्योंकि स्क्रॉलिंग शुरू होने से पहले तालिका दृश्य सेल हमेशा कुछ मिलीसेकंड के लिए हाइलाइट किया जाएगा।

दूसरी बात मैंने कोशिश की

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event 

ओवरराइड करने के लिए था, क्योंकि मैं पढ़ा था कि पुस्तक दृश्य हमेशा ही देता है, ताकि वह अपने subviews से "चोरी" होगा छूता है और बाद में उन्हें subview लिए भेज अगर वे स्क्रॉल व्यू के लिए रूचि नहीं रखते थे। हालांकि, यह अब और सत्य नहीं है। UIScrollView का हिटटेस्ट का डिफ़ॉल्ट कार्यान्वयन: withEvent: वास्तव में उस सबव्यूव को देता है जो स्पर्श प्राप्त करना चाहिए। इसके बजाय यह स्पर्श को रोकने के लिए इशारा पहचानकर्ताओं का उपयोग करता है।

तो मैंने जो तीसरी चीज का प्रयास किया था वह मेरा खुद का इशारा पहचानकर्ता लागू करना था और अगर स्पर्श पिकर व्यू के बाहर था और अन्यथा सफल हो गया तो यह असफल हो गया। तब मैं विफल सभी स्क्रॉल दृश्य का इशारा recognizers सेट जब तक मेरी इशारा पहचानकर्ता निम्नलिखित कोड का उपयोग कर विफल रहा:

for (UIGestureRecognizer * gestureRecognizer in self.tableView.gestureRecognizers) 
{ 
    [gestureRecognizer requireGestureRecognizerToFail:myRecognizer]; 
} 

यह वास्तव में पुस्तक देखने से छूता चोरी करता है, लेकिन पिकर दृश्य उन्हें कभी नहीं मिलती। इसलिए मैं हालांकि शायद मैं सिर्फ सभी छूता है कि मेरे इशारे पहचानकर्ता इस कोड का उपयोग करने पर प्राप्त भेज सकता है:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 
{ 
    for (UITouch *touch in touches) 
     [touch.view touchesBegan:touches withEvent:event]; 
} 

ऊपर कोड एक सरलीकृत संस्करण है। मैं यह भी सुनिश्चित करता हूं कि दृश्य एक पिकर व्यू (या इसके सबव्यूव्स में से एक है) और उपरोक्त वर्णित इशारा पहचानकर्ता के लिए उचित स्थिति निर्धारित करें। मैंने रद्द, समाप्त और स्थानांतरित करने के लिए भी ऐसा ही किया। हालांकि, पिकर व्यू अभी भी जवाब नहीं दे रहा था।

मैंने अपने नियमित काम पर लौटने से पहले एक आखिरी चीज़ भी कोशिश की। मेरी व्यापक Googling के दौरान मैंने पढ़ा है कि नेस्टेड UIScrollViews सिर्फ जादुई 3.x के बाद से काम किया है, इसलिए मैं एक नेस्टेड UIScrollView अंदर मेरे पिकर दृश्य डालने की कोशिश की है और उस पर निम्नलिखित गुण सेट:

scrollView.delaysContentTouches = NO; 
scrollView.canCancelContentTouches = NO; 

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

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

पूरे प्रश्न को पढ़ने के लिए धन्यवाद और यहां तक ​​कि अगर आपको जवाब नहीं पता है तो भी आप सवाल को ऊपर उठा सकते हैं ताकि इसे अधिक ध्यान दिया जा सके (उम्मीद है कि किसी ऐसे व्यक्ति से जो इसका जवाब दे सके)। धन्यवाद! :)

उत्तर

32

कभी-कभी आपको उत्तर प्राप्त करने से पहले प्रश्न पूछना होगा। दान रे की एक ही समस्या थी और इसे एक बहुत ही अलग समाधान के साथ हल किया गया।

- (UIView*)hitTest:(CGPoint)point withEvent:(UIEvent *)event 
{ 
    UIView* result = [super hitTest:point withEvent:event]; 

    if ([result.superview isKindOfClass:[UIPickerView class]]) 
    { 
     self.scrollEnabled = NO; 
    } 
    else 
    { 
     self.scrollEnabled = YES;  
    } 
    return result; 
} 

मैंने कोड का परीक्षण किया है और यह मेरे लिए भी ठीक काम करता है। हालांकि, यह वास्तव में स्क्रॉल व्यू से स्पर्श नहीं कर रहा है, इसलिए यदि कोई जानता है कि वास्तव में स्पर्श को कैसे चुराया जाए तो यह बहुत अच्छा होगा।

स्रोत: UIPickerView inside UITableView.tableFooterView doesn't receive drag touches

+0

चूंकि यह अभी भी केवल जवाब है, मैं इसे अपने जवाब के रूप में स्वीकार करेंगे के लिए, लेकिन अगर आपके पास एक बेहतर समाधान है, इसे साझा करने में संकोच नहीं करें! –

+0

यह मेरा पसंदीदा समाधान है। यह दुबला और मतलब है और बस काम करता है। आपका बहुत बहुत धन्यवाद! – DrMickeyLauer

+1

उत्कृष्ट, मेरी ज़रूरतों के लिए मैंने इसे '([परिणाम isKindOfClass: [UITableView क्लास]] || [परिणाम। सुपरव्यू isKindOfClass: [UITableView क्लास]] || [परिणाम.superview isKindOfClass: [UITableViewCell क्लास]]) ' – Diziet

4

एक थोड़ी देर हो चुकी है, लेकिन मैं इस समाधान पाया: http://www.cocoanetics.com/2010/06/hacking-uiscrollview-gesture-recognizers/ वर्क्स मुझे

+2

सीधे लिंक के बजाय आपके उत्तर में आलेख के प्रासंगिक भाग को शामिल करने के लिए सर्वश्रेष्ठ – brandonscript