2014-12-02 3 views
2

У меня есть карта с аннотациями, где я выполнить следующие действия:Проверьте, пользователь выбрал другую аннотацию на карте

- (void)mapView:(MKMapView *)mapView didDeselectAnnotationView:(MKAnnotationView *)view{ 
[self methodA];} 


- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view{ 
[self methodB];} 

Оба метода A и B удалить или добавить мнение в mapView.superview.

Все работает отлично, имея дело с одной аннотацией. Проблема в том, что у меня есть несколько аннотаций, и я выбираю два, один за другим.

Если я нахожусь в другом месте на карте, все работает нормально. Но когда я нажимаю во втором аннотационном представлении после первого, он выполняет «didDeselectAnnotationView», а затем «didSelectAnnotationView», который вызывает оба метода A и B, и это не то, что я хочу. Я хотел бы, чтобы он обнаружил, что я нажимаю в другой аннотации и игнорирую оба метода.

Я исследовал об этом, но пока не нашел решения.

Я попытался добавить глобальную переменную и играть с ним, а также определить, когда пользователь прикасается:

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{ 

UITouch *touch = [touches anyObject]; 

// Get the specific point that was touched 
CGPoint point = [touch locationInView:self.mapView]; 

for (id<MKAnnotation> annotation in self.mapView.annotations) { 
    MKAnnotationView* anView = [self.mapView viewForAnnotation: annotation]; 
    if (anView){ 

     CGRect frame = CGRectMake(anView.frame.origin.x-5, anView.frame.origin.y-5, anView.frame.size.width+5, anView.frame.size.height+5); 
     if (CGRectContainsPoint(frame, point)) { 

      NSLog(@"BELONGS"); 
     } 

    } 

}} 

Однако это не поймать все штрихи плюс это будет немного спагетти.

Любые идеи, как это решить?

Все лучшее

+0

Возможно похожи: http://stackoverflow.com/questions/23667606/detect-when-a-second-annotation-is-selected-in- a-mkmapview – Anna

+0

В принятом ответе используется [self performSelector: @selector (checkShouldHideBottomView :) withObject: view afterDelay: 0.5]; Я считаю, что это не соответствующая вещь. – jonypz

ответ

0

Делегат не делает никакого различия между случаем, когда вы отменяете выбор, а затем выбрать другой вид аннотаций и случай, в котором можно выбрать новый вид аннотаций в то время как один уже выбран. В обоих случаях эти вызовы будут осуществляться в таком порядке:

  • didDeselect view1
  • didSelect view2

Вы хотите 2 вещи:

1) не называют methodB, когда выбор View2 очень близко (по времени) к отмене выбора1.

2) не вызов методА когда выбор близок (по времени) к предыдущему выбору.

Для решения этих двух проблем вы можете сохранить две метки времени: 1) последний выбор 2) последний отбор. С помощью этих двух переменных вы можете установить порог, чтобы определить, что означает «close» в двух приведенных выше правилах.

Теперь у вас есть условие для предотвращения вызова метода А и метода В в конкретном случае быстрого выбора и выбора (что действительно происходит для делегата при переключении с одного выбора на другой).

+0

Временная метка не решит мою проблему, я считаю. Предполагается, что пользователь может щелкнуть аннотацию на аннотацию без какого-либо внешнего поведения (добавление или удаление других представлений -> методA и методB) – jonypz

+0

Я обновил свой ответ. Теперь это должно быть ясно. – ffarquet

+0

Это будет работать, только если я поставлю порог в бесконечное число, и он должен сбросить это значение, когда пользователь щелкает за пределами аннотации. Это все еще отрывочное решение. – jonypz

0
- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)aView 
{ 
    indexPathTag=aView.tag; 
    [mapView deselectAnnotation:aView.annotation animated:YES]; 

} 
- (void)mapView:(MKMapView *)mapView didDeselectAnnotationView:(MKAnnotationView *)aView 
{ 
} 

call deselectAnnotation from didSelectAnnotationView.

+0

не работает. такое же поведение – jonypz

0

Вот мое текущее решение. Хотя я не люблю его, он работает сейчас. Если у вас есть лучший, отправьте ответ, и я пометю его как правильный.

Я использую глобальную переменную, чтобы отслеживать текущую выбранную аннотацию. Я инициализирую его как ноль.

- (void)mapView:(MKMapView *)mapView didDeselectAnnotationView:(MKAnnotationView *)view{ 

[self performSelector:@selector(numberOfSelectedAnnotations) 
      withObject:view.annotation afterDelay:.5]; 
} 

- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view{ 
     if (self.selectedAnnotation == nil) { 
     [self methodB]; 
     } 
    self.selectedAnnotation = (MKAnnotationView*)view; 
} 


-(void)numberOfSelectedAnnotations{ 
if (self.mapView.selectedAnnotations.count == 0) { 
    [self methodA]; 
    self.selectedAnnotation = nil; 
    } 
} 
-1

Это мое предпочтительное решение:

private var selectedAnnotationView: MKAnnotationView? 

func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView? { 
    if let _ = annotation as? MKUserLocation { 
     return nil 
    } 
    let ident = "MyAnnotation" 
    let pin = mapView.dequeueReusableAnnotationViewWithIdentifier(ident) as? MKPinAnnotationView ?? MKPinAnnotationView(annotation: annotation, reuseIdentifier: ident) 
    pin.animatesDrop = true 
    pin.canShowCallout = true 
    pin.addGestureRecognizer(UITapGestureRecognizer(target: self, action: "annotationTapped:")) 
    pin.rightCalloutAccessoryView = UIButton(type: .InfoDark) 
    return pin 
} 

// This will get called before didDeselectAnnotationView below 
func annotationTapped(tapGesture: UITapGestureRecognizer) { 
    if let annotationView = tapGesture.view as? MKAnnotationView { 

     if annotationView === self.selectedAnnotationView { 
      // same as last time 
     } else { 
      // different annotation view 
     } 

     self.selectedAnnotationView = annotationView 

     // any other logic for handling annotation view tap 
    } 
} 

func mapView(mapView: MKMapView, didDeselectAnnotationView view: MKAnnotationView) { 
    if view === self.selectedAnnotationView { 

     // The user did not select another annotation view 
     // (e.g. they tapped the map)    

     self.selectedAnnotationView = nil 
    } 
}