8

I have a UITapGestureRecognizer setup to add an annotation onto the map where the user clicks. The problem I'm running into is when the user taps an existing annotation to view the tooltip, the tooltip pops up, but another annotation is added to the map behind the clicked annotation. Is there a way to detect if an annotation was tapped and return before adding the annotation?

This is my viewDidLoad:

UITapGestureRecognizer *singleTapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(foundTap:)];
singleTapRecognizer.numberOfTapsRequired = 1;
[self.mapView addGestureRecognizer:singleTapRecognizer];

And my on touch function:

-(IBAction)foundTap:(UITapGestureRecognizer *)recognizer
{
    CGPoint point = [recognizer locationInView:self.mapView];

    CLLocationCoordinate2D tapPoint = [self.mapView convertPoint:point toCoordinateFromView:self.view];

    AGIAnnotation * annotation = [[AGIAnnotation alloc] initWithCoordinate:tapPoint];
    // Some other stuff

    [self.mapView addAnnotation:annotation];
}

Any help is appreciated.

DoubleHolo
  • 157
  • 1
  • 10
  • Unrelated note: In the convertPoint call, you might want to use `toCoordinateFromView:self.mapView` instead of `self.view`. The `self.view` will only work if the map view takes up the whole screen. If you change your map view to be smaller than the screen (especially if its origin is not 0,0), you'll get the wrong point back. –  Feb 06 '14 at 23:30

2 Answers2

6

There is a UIGestureRecognizerDelegate Protocol

Implement gestureRecognizer:shouldReceiveTouch: and return NO if the touch is on an existing tooltip. Something like this:

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
    if ([touch.view isKindOfClass:[MKPinAnnotationView class]])
    {
        return NO;
    }
    return YES;
}
Shmidt
  • 16,436
  • 18
  • 88
  • 136
Michael Behan
  • 3,433
  • 2
  • 28
  • 38
3

@mbehan answer in Swift 3+:

in ViewDidLoad:

let singleTapRecognizer = UITapGestureRecognizer(target: self, action: #selector(YourClass.foundTap(_:)))
singleTapRecognizer.delegate = self
mapView.addGestureRecognizer(singleTapRecognizer)

and the UIGestureRecognizerDelegate extension:

extension YourClass: UIGestureRecognizerDelegate {
  func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
    return !(touch.view is MKPinAnnotationView)
  }
}
Federico Zanetello
  • 3,321
  • 1
  • 25
  • 22
  • looked high and low for an answer that match my setup and couldn't find anything till seeing this! – user1019042 Nov 05 '16 at 15:51
  • 1
    the solution is great, but if you have many pins in your mapview like over 50 of them, the running of the result = !(touch.view is MKPinAnnotationView) takes forever – user1019042 Nov 06 '16 at 04:20
  • Oh, that's strange! The code above doesn't run through all the pins obviously. Maybe file a radar? – Federico Zanetello Nov 06 '16 at 04:25