2014-06-12 30 views
5

Özel bir çağrıyı gösteren özel bir MKPinAnnotationView alt sınıfım var. Bu açıklamadaki dokunma olaylarını ele almak istiyorum.MKMapView seçimini değiştirmeyi önleme (temiz)

Çalışan bir çözümüm var (aşağıda) ama sadece doğru değil. Bir başparmak kuralı var, ne zaman performSelector: .. withDelay: kullanıyorsam, onunla çalışmak yerine sistemle savaşıyorum.

Herkesin, MKMapView'ın agresif olay işleme ve ek açıklama seçimi işlemek için iyi ve temiz bir çözümü var mı?

Benim şimdiki çözüm:

benim jest recognisers Harita Görünümü olarak kovma bu olmadan (kendi vuruş testi yapmak (Bütün ek açıklama seçimi sınıfından kodu)

olayları tüketir :

- (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; 
} 

benim setSelected geçersiz I seçimi kaldırmaya görmezden böylece ben de seçimleri kapatmak Not

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]; 
    } 


} 

Bu beğenmediğim hat yorumunu beğenmedim ama teta gecikmeli yangının sonunda da oldukça tüylü. MapView'a ulaşmak için superview zincirine geri dönmem gerekiyor, böylece seçimin hala yerinde olduğuna inanıyorum.

-(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; 
} 

ile

// 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; 

} 

Bu, tüm olmadan ve olumsuz (diğer çözümlerden gördüğüm titrek gibi çalışıyor gibi görünüyor. Nispeten basit ama o doğru gelmiyor.

herkes Daha iyi bir çözüme sahip misiniz?

cevap

1

Harita görünümünün seçim takibi ile maymun yapman gerektiğini sanmıyorum Eğer doğru neyi istediğinizi yorumluyorsam, Sadece hitTest:withEvent: geçersiz kılma ile ve canShowCalloutNO olarak ayarlanmış olarak kullanın. setSelected:'da belirtme çizgisi görünümü/kaybolma animasyonunuzu uygun şekilde gerçekleştirin. Ayrıca setHighlighted:'u geçersiz kılmalı ve görünürse özel belirtme ekranınızın görünümünü ayarlamalısınız.

İlgili konular