2014-06-12 14 views
5

Mam niestandardową podklasę MKPinAnnotationView, która wyświetla niestandardowe wywołanie. Chcę obsługiwać zdarzenia dotykowe wewnątrz tej adnotacji.Zapobieganie zmianie wyboru MKMapView (czyszczenie)

Mam działające rozwiązanie (poniżej), ale po prostu nie czuję się dobrze. Mam zasadę, że za każdym razem, gdy używam performSelector: .. withDelay:, walczę z systemem, zamiast z nim pracować.

Czy ktoś ma dobre, czyste obejście dla agresywnej obsługi zdarzeń MKMapView i obsługi zaznaczania adnotacji?

Moje obecne rozwiązanie:

(Cały kod z mojej klasy selekcji adnotacji)

zrobić własne badania trafień (bez tego moje rozpoznające gest nie ogień jako widoku mapy zużywa wydarzenia :

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

pamiętać, że także wyłączyć wybrane tak, że w moim nadpisane setSelected mogę zignorować cofnięcia wyboru

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


} 

To linia, którą skomentowałam , której nie lubię, ale jest też dość owłosiona pod koniec opóźnionego ognia theta. Muszę wrócić do łańcucha podglądu, by dostać się do mapView, dzięki czemu mogę przekonać, że selekcja nadal obowiązuje.

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

} 

z

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

To wszystko wydaje się działać bez i minusem (jak migotanie widziałem od innych rozwiązań. Jest to stosunkowo proste, ale nie czuje się dobrze.

Każdy masz lepsze rozwiązanie?

Odpowiedz

1

Nie sądzę, że musisz małpować śledzenie wyboru widoku mapy.Jeśli poprawnie interpretuję to, czego chcesz, powinieneś być w stanie sompletuj go tylko z nadpisaniem hitTest:withEvent: i canShowCallout ustawionym na NO. W trybie setSelected: wykonaj odpowiednio animację wyglądu/znikania objaśnień. Należy również zastąpić setHighlighted: i dostosować wyświetlanie niestandardowego objaśnienia, jeśli jest ono widoczne.

Powiązane problemy