2014-06-12 5 views
5

मेरे पास MKPinAnnotationView का कस्टम सबक्लास है जो एक कस्टम कॉल आउट प्रदर्शित करता है। मैं उस एनोटेशन के अंदर टच इवेंट्स को संभालना चाहता हूं।MKMapView बदलते चयन को रोकना (साफ-सफाई)

मेरे पास एक कामकाजी समाधान है (नीचे) लेकिन यह सही नहीं लगता है। मेरे पास अंगूठे का नियम है कि जब भी मैं performSelector: .. withDelay: का उपयोग करता हूं, तो मैं इसके साथ काम करने के बजाय सिस्टम से लड़ रहा हूं।

क्या किसी के पास MKMapView और एनोटेशन चयन हैंडलिंग के आक्रामक ईवेंट हैंडलिंग के लिए एक अच्छा, साफ कामकाज है?

मेरे वर्तमान समाधान:

(मेरी टिप्पणी के चयन वर्ग से सभी कोड)

मैं अपने ही हिट परीक्षण करना (यह मेरा इशारा recognisers मानचित्र दृश्य के रूप में आग नहीं है बिना ईवेंट की खपत :

- (UIView*)hitTest:(CGPoint)point withEvent:(UIEvent*)event; { 
    // To enable our gesture recogniser to fire. we have to hit test and return the correct view for events inside the callout. 

    UIView* hitView = nil; 

    if (self.selected) { 
     // check if we tpped inside the custom view 
     if (CGRectContainsPoint(self.customView.frame, point)) 
      hitView = self.customView; 
    } 

    if(hitView) { 
     // If we are performing a gesture recogniser (and hence want to consume the action) 
     // we need to turn off selections for the annotation temporarily 
     // the are re-enabled in the gesture recogniser. 
     self.selectionEnabled = NO; 

     // *1* The re-enable selection a moment later 
     [self performSelector:@selector(enableAnnotationSelection) withObject:nil afterDelay:kAnnotationSelectionDelay]; 

    } else { 
     // We didn't hit test so pass up the chain. 
     hitView = [super hitTest:point withEvent:event]; 
    } 

    return hitView; 
} 
ध्यान दें कि मैं भी इतना है कि मेरी अधिरोहित में setSelected मैं अचयन अनदेखा कर सकते हैं चयन बंद कर देते हैं

0।
- (void)setSelected:(BOOL)selected animated:(BOOL)animated; { 
    // If we have hit tested positive for one of our views with a gesture recogniser, temporarily 
    // disable selections through _selectionEnabled 
    if(!_selectionEnabled){ 
     // Note that from here one, we are out of sync with the enclosing map view 
     // we're just displaying out callout even though it thinks we've been deselected 
     return; 
    } 

    if(selected) { 
     // deleted code to set up view here 
     [self addSubview:_customView]; 

     _mainTapGestureRecogniser = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(calloutTapped:)]; 
     [_customView addGestureRecognizer: _mainTapGestureRecogniser]; 

    } else { 
     self.selected = NO; 
     [_customView removeFromSuperview]; 
    } 


} 

यह पंक्ति पर टिप्पणी की गई है कि मुझे पसंद नहीं है लेकिन यह भी देरी की आग में अंत में सुंदर बालों वाली है। मुझे नक्शा देखने के लिए पर्यवेक्षण श्रृंखला का बैक अप लेना होगा ताकि मैं इसे समझ सकूं कि चयन अभी भी जगह पर है।

// Locate the mapview so that we can ensure it has the correct annotation selection state after we have ignored selections. 
- (void)enableAnnotationSelection { 
    // This reenables the seelction state and resets the parent map view's idea of the 
    // correct selection i.e. us. 
    MKMapView* map = [self findMapView]; 
    [map selectAnnotation:self.annotation animated:NO]; 
    _selectionEnabled = YES; 

} 

-(MKMapView*)findMapView; { 
    UIView* view = [self superview]; 
    while(!_mapView) { 
     if([view isKindOfClass:[MKMapView class]]) { 
      _mapView = (MKMapView*)view; 
     } else if ([view isKindOfClass:[UIWindow class]]){ 
      return nil; 
     } else{ 
      view = [view superview]; 
      if(!view) 
       return nil; 
     } 
    } 

    return _mapView; 
} 

साथ

यह सब बिना और नकारात्मक पक्ष (झिलमिलाहट मैं अन्य समाधान से देखा है की तरह काम करने लगता है। यह अपेक्षाकृत सीधा है, लेकिन यह सही नहीं लगता है।

किसी को भी एक बेहतर समाधान है?

उत्तर

1

मुझे नहीं लगता कि आपको मानचित्र दृश्य के चयन ट्रैकिंग के साथ बंदर की आवश्यकता है। अगर मैं सही तरीके से व्याख्या कर रहा हूं, तो आप एसीसी इसे hitTest:withEvent: ओवरराइड के साथ छोड़ दें और canShowCalloutNO पर सेट करें। setSelected: में तदनुसार अपनी कॉलआउट उपस्थिति/गायब एनीमेशन निष्पादित करें। आपको setHighlighted: को ओवरराइड करना चाहिए और दृश्यमान होने पर अपने कस्टम कॉलआउट के प्रदर्शन को समायोजित करना चाहिए।