Ignore mapView: didSelectAnnotationView on long press

I struggle with that. I have a map with many contacts in a small area. I want to ignore the choice of the type of annotation when I click on the map for a long time, regardless of whether I click on the annotation. It seems that the annotation is selected on touchDown, rather than being pressed internally on the annotation view, which is annoying.

I added a longpress gesture to the map:

UILongPressGestureRecognizer *longRec = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(addPin:)];
longRec.cancelsTouchesInView = YES;
[self.mapView addGestureRecognizer:longRec];

This is not recognized when I click on the annotation for a long time. As soon as I click the "Delete" button, the annotation processing request is processed, and a long press never works.

I tried to block the click gesture recognizer, which of course does not work, because the mapview display gesture is not passed to my map display controller, so this does not work:

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
    if ([gestureRecognizer isKindOfClass:[UITapGestureRecognizer class]] && [otherGestureRecognizer isKindOfClass:[UILongPressGestureRecognizer class]]) {
        return NO;
    }
    return YES;
}

I also tried adding a longpress gesture to the presentation of the annotation as a hack, but it never starts, and I still don't like this strategy.

Is there a way to block the selection of the mapview annotation when the longpress gesture is pending review on the map?

+3
source share
2 answers

It turned out a solution. Mostly subclassing MKMapView and implementing handleTap and handleLongPress.

There I block a short press. I also give a slight delay to consider the case when both gestures are recognized simultaneously:

@implementation KWMapView // :MKMapView

- (void)handleTap:(UITapGestureRecognizer *)tapGesture
{
    CGPoint tapPoint = [tapGesture locationInView:self];
    NSUInteger numberOfTouches = [tapGesture numberOfTouches];

    if (numberOfTouches == 1 && tapGesture.state == UIGestureRecognizerStateEnded) {
        if (!self.blockTap) {
            id v = [self hitTest:tapPoint withEvent:nil];

            if ([v isKindOfClass:[MKAnnotationView class]]) {
                [self addAnnotation:[v annotation]];
                [self selectAnnotation:[v annotation] animated:YES];
            } else {
                [[NSNotificationCenter defaultCenter] postNotificationName:PNMapViewDidTapMap object:tapGesture];
            }
        }
    }
}

- (void)handleLongPress:(UILongPressGestureRecognizer*)sender {
    self.blockTap = YES;

    if (sender.state == UIGestureRecognizerStateBegan) {
        [[NSNotificationCenter defaultCenter] postNotificationName:PNMapViewDropPinGesture object:sender];
    }

    if (sender.state == UIGestureRecognizerStateEnded || sender.state == UIGestureRecognizerStateCancelled || sender.state == UIGestureRecognizerStateFailed) {
        double delayInSeconds = .2;
        dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
        dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
            self.blockTap = NO;
        });
    }
}
@end
+2
source

, , , - , , .

0

All Articles