2011-07-28 15 views
7

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

  1. बटन और अन्य नियंत्रण उत्तरदायी नहीं हैं।
  2. मैं - (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent*)event के कार्यान्वयन के अनुसार स्पर्श को अवरुद्ध करना चाहता हूं - अगर मैं हाँ वापस कर दूं तो मैं नहीं चाहता कि स्पर्श MKMapView (संभावित रूप से अन्य एनोटेशन जो मेरे एनोटेशन व्यू के पीछे हैं) को भेजना चाहते हैं। , मैं इस मामले में खुद को स्पर्श करना चाहता हूं।

मुझे यकीन है कि बना दिया है userInteractionEnabledYES पर सेट है और मैं जांच की है कैसे छूता कस्टम एनोटेशन देखने के लिए touchesBegan आदि अधिभावी द्वारा (MKAnnotationView की मेरी उपवर्ग) भेजा जाता है - लेकिन ऐसा लगता है कि अंतिम रूप आमतौर पर रद्द कर दिया जाता है (सोचा कि मैंने कुछ बार touchesEnded प्राप्त करने में कामयाब रहा है) - ऐसा लगता है कि कस्टम एनोटेशन व्यू के साथ किसी भी उपयोगकर्ता-इंटरैक्शन को मैन्युअल रूप से कार्यान्वित करना मुश्किल होगा।

क्या किसी के पास MKAnnotationView ऑब्जेक्ट्स के साथ अधिक उपयोगकर्ता इंटरैक्शन की अनुमति देने में कोई अंतर्दृष्टि है?

+0

आप कुछ कोड पोस्ट करने में सक्षम हैं आप MKAnotationView में अपने यूआईसींट्रोल को कैसे जोड़ रहे हैं? – Ricky

+1

कॉलआउट में बटन डालने के लिए बेहतर है, एनोटेशन –

+0

@Pennypacker मेरे पास इसके अंदर घोंसले वाले नियंत्रणों के साथ एक यूवी व्यू है, यह UIView ऐप में कहीं और भी उपयोग किया जाता है। UIView को मेरे कस्टम एनोटेशन व्यू में जोड़ा गया है। – jhabbott

उत्तर

5

मैंने इसे एक सहयोगी की मदद से हल करने में कामयाब रहे। समाधान - (UIView*)hitTest:(CGPoint)point withEvent:(UIEvent*)event ओवरराइड करना है। हमारी धारणा यह है कि MKAnnotationView (जो आपके एनोटेशन व्यू को उत्तराधिकारी होना चाहिए) इसे 'गलत' चीज करने के लिए ओवरराइड करता है (संभवतः एनोटेशन चयन ओवरलैपिंग एनोटेशन के बीच अवरुद्ध नहीं होता है)। तो आपको सही चीज़ करने के लिए इसे फिर से ओवरराइड करना होगा और उपयुक्त UIView वापस कर देना होगा, फिर सिस्टम इसे ईवेंट भेजेगा और उपयोगकर्ता इसके साथ बातचीत करने में सक्षम होगा :)। इसमें फायदेमंद (इस मामले में) दुष्प्रभाव है कि इंटरैक्टिव एनोटेशन इसके पीछे एनोटेशन के चयन को अवरुद्ध करता है।

+0

मैं अभी भी यह कार्य करने की कोशिश कर रहा हूं कि इसे स्वयं कैसे कार्यान्वित किया जाए ... क्या आप 'एमकेएएनोटेशन व्यू' या 'एमकेमैप व्यू' के अंदर 'हिटटेस्ट: साथवें:' ओवरराइड करते हैं? यदि यह 'MKMapView' है तो इसका मतलब है कि मुझे विधि को ओवरराइड करने के लिए इसे उप-वर्ग करना होगा? आपको किस दृश्य को वापस करने की आवश्यकता है, 'rightCalloutAccessoryView' या' MKAnotationView'? – jowie

+1

अपने कस्टम व्यू क्लास के साथ सबक्लास 'एमकेएनोटेशन व्यू' और ओवरराइड 'हिटटेस्ट: साथ:' - यहां से आप दृश्य को स्वयं ही वापस कर सकते हैं, या इसके सबव्यूव्स (उदाहरण के लिए एक बटन या अन्य इंटरैक्टिव ऑब्जेक्ट) - स्पर्श उस पर भेजे जाएंगे राय। – jhabbott

+0

आश्चर्यजनक रूप से, यह मेरे लिए काम नहीं करता है। एकमात्र चीज जो मैं काम कर सकता हूं वह है 'प्वाइंट इनसाइड: इनवेन्ट' को लागू करना और 'हाँ' वापस करना। फिर भी, यह सामान्य पिन एनोटेशन के साथ ठीक काम करता है, लेकिन न तो विधियां उपयोगकर्ता स्थान पिन एनोटेशन के साथ काम करती हैं। – jowie

0

मैंने पाया कि hitTest:withEvent: ओवरराइड करने के बजाय मैं बस pointInside:withEvent: को ओवरराइड कर सकता हूं और इसे YES वापस लौटा सकता हूं। मुझे लगता है कि आधिकारिक तौर पर मुझे यह सुनिश्चित करने के लिए एक पॉइंट-रेक्ट अंतरंग जांच करनी चाहिए कि जिस स्थान पर मैं टैप कर रहा हूं, वह नियंत्रण तत्व के भीतर है, लेकिन व्यावहारिक रूप से, return YES डालने से पूरी तरह से काम करना प्रतीत होता है, फिर भी आपको टैप करके MKAnnotationView को खारिज करने की अनुमति मिलती है इससे दूर

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event 
{ 
    // for testing purposes 
    BOOL result = [super pointInside:point withEvent:event]; 
    NSLog(@"pointInside:RESULT = %i", result); 

    return YES; 
} 
+0

यदि आप केवल पॉइंट इनसाइड को ओवरराइड करते हैं: साथ, तो आपके इंटरैक्टिव एनोटेशन के पीछे * किसी भी अन्य एनोटेशन * को अभी भी चुना जा सकता है, इस प्रकार सक्रिय एक को चुनना। आपको हिटटेस्ट को ओवरराइड करने की आवश्यकता है: अन्य ओवरलैपिंग (यानी पीछे) एनोटेशन पर भेजे जाने वाले स्पर्श को अवरुद्ध करने के लिए। – jhabbott

+0

तो जब आप 'पॉइंट इनसाइड ओवरराइड करते हैं: साथ:' क्या आप इसे बुलबुले से अवरुद्ध करने के लिए सिर्फ शून्य वापस करते हैं? – jowie

+0

नहीं, मुझे लगता है कि 'बुलबुले' से आपका मतलब कॉलआउट पॉप अप हो रहा है? मेरा प्रश्न/समाधान तब होता है जब आप कॉलआउट का उपयोग नहीं कर रहे हैं (क्योंकि वे बहुत अनुकूल नहीं हैं) और इसके बजाय कस्टम एनोटेशन का उपयोग करना (कस्टम एनोटेशन जोड़ना जब आपके किसी अन्य 'पिन' एनोटेशन का चयन किया जाता है)। – jhabbott

0

झाबॉट के जवाब में जोड़ना, यह मेरे लिए काम करता है। मेरे पास एक कस्टम एनोटेशन व्यू MKCustomAnnotationView है जिसमें एनोटेशन के रूप में एक कस्टम एनोटेशन CustomPin है। उस 'पिन' में UIButton सहायक उपकरण प्रतिस्थापन के रूप में रखता है जिसे मैं स्पर्श ईवेंट प्राप्त करना चाहता था।

मेरे hitTest विधि इस प्रकार दिखाई देगा:

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event 
{ 
    UIView *result = [super hitTest:point withEvent:event]; 
    //NSLog(@"ht: %f:%f %d %@", point.x, point.y, [[event touchesForView:self] count], result); 

    if ([result isKindOfClass:[MKCustomAnnotationView class]]) 
    { 
     MKCustomAnnotationView *av = (MKCustomAnnotationView *)result; 
     CustomPin *p = av.annotation; 
     UIButton *ab = p.accessoryButton; 
     if (p.calloutActive && point.x >= ab.frame.origin.x) 
      return ab; 
    } 

    return result; 
} 

calloutActive bool शायद ज्यादातर मामलों में आवश्यक नहीं है।

0

इस के तल पर जवाब एक AnnotationView subview तो करने के लिए एक tapGesture जोड़ने के लिए देख किसी को भी के लिए:

MKannotationView with UIButton as subview, button don't respond

मेरे लिए काम किया:

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event 
{ 
    if (CGRectContainsPoint(_button.frame, point)) { 
     return _button; 
    } 
    return [super hitTest:point withEvent:event]; 
}