4

On my mapview I draw polygon overlays that belong to a specific annotation. I want that annotation to be selected when the overlay is tapped. My first attempt was to add a UITapGestureRecognizer to the mapview, test whether the tapped point is inside a polygon and perform [mapView selectAnnotation:myAnnotation] on success. The problem is that after this, the mapview decides there was a tap not on any annotations, so it deselects the annotation again.

My question is how to best prevent this from happening, I don't seem to be able to find a nice solution. What I have tried:

  • Create a new UIGestureRecognizer subclass that recognizes just taps inside overlays, then iterate through mapView.gestureRecognizers and call requireGestureRecognizerToFail on each. However, the mapview does not expose any recognizers through its property.
  • Return YES for shouldBeRequiredToFailByGestureRecognizer in my custom recognizer for any other recognizer that isKindOfClass tap recognizer. However, there still seems to be another recognizer that is not passed in there.
  • Place a transparent view on there and do the polygon check in pointInside:withEvent, but does also blocks any other gestures besides only taps.

EDIT:

After poking around a bit more, I have code that is almost working, of which I know where it goes wrong. I have a custom recognizer as before. In its delegate I do:

- (BOOL)gestureRecognizer:(UIGestureRecognizer*)gestureRecognizer
shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer*)otherGestureRecognizer
{
    [otherGestureRecognizer requireGestureRecognizerToFail:gestureRecognizer]; // can possibly do this in custom recognizer itself instead
    return YES;
}

Now taps inside polygons successfully prevent deselection. However, when I then do:

- (void)mapView:(MKMapView *)mapView didSelectAnnotationView
{
    // displayRegion is chosen to center annotation
    [mapView setRegion:self.displayRegion animated:YES];
}

it breaks again, and the annotation gets deselected again..

sgvd
  • 3,819
  • 18
  • 31

1 Answers1

0

It seems we have the same problem ( a little different: i'm tryng to select manually an annotation in a gesture recognizer )

I'm doing so ( and it works, but it seems to complex to me , feel free to ask more if it's not clear ):

i'm working with a long pressure event :

...
_lp1 = [[UILongPressGestureRecognizer alloc] 
        initWithTarget:self action:@selector(handleOverlayLp1:)];
((UILongPressGestureRecognizer*)_lp1).minimumPressDuration = 0.05;
_lp1.delegate = self;

[_mapView addGestureRecognizer:_lp1];
...

I collect all gesture recognizers in a global var :

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {

if (_gestureRecognizers==nil)
    _gestureRecognizers = [NSMutableSet set];
[_gestureRecognizers addObject:otherGestureRecognizer];
return YES;
}

// when i recognize gestures, disable everything and call an asyncrhronous task where i re-enable
- (void)handleOverlayLp1:(UIGestureRecognizer*)recognizer
{

    // Do Your thing. 
    if (recognizer.state == UIGestureRecognizerStateBegan)
    {

        BOOL found=NO;

        ...

        if (found) {
            // disable gestures, this forces them to fail, and then reenable in selectOverlayAnnotation that is called asynchronously
            for (UIGestureRecognizer *otherRecognizer in _gestureRecognizers) {
                otherRecognizer.enabled = NO;
                [self performSelector:@selector(selectOverlayAnnotation:)  withObject:polyline afterDelay:0.1];
            }
        }
    }
}

- (void)selectOverlayAnnotation: (id<MKAnnotation>) polyline
{
    [_mapView selectAnnotation:polyline animated:NO];
    for (UIGestureRecognizer *otherRecognizer in _gestureRecognizers) {
        otherRecognizer.enabled = YES;
    }
}
sgvd
  • 3,819
  • 18
  • 31
atrebbi
  • 553
  • 3
  • 20
  • It seems a bit dirty yes.. :) I am also not sure it does more than what my code already does, using `requireGestureRecognizerToFail`: preventing all other recognizers to fail when the custom one succeeds? Also, not that `shouldRecognizeSimultaneouslyWithGestureRecognizer` on every gesture, so you will keep adding the same recognizers to your list multiple times. – sgvd May 15 '14 at 15:02