MKAnnotationView and tap detection

前端 未结 6 1279
攒了一身酷
攒了一身酷 2020-12-09 21:29

I have a MKMapView. I added a UITapGestureRecognizer with a single tap.

I now want to add a MKAnnotationView to the map. I can

6条回答
  •  离开以前
    2020-12-09 21:46

    There might be a better and cleaner solution but one way to do the trick is exploiting hitTest:withEvent: in the tap gesture recognized selector, e.g.

    suppose you have added a tap gesture recognizer to your _mapView

    - (void)tapped:(UITapGestureRecognizer *)g
    {
        CGPoint p = [g locationInView:_mapView];
        UIView *v = [_mapView hitTest:p withEvent:nil];
    
        if (v ==  subviewOfKindOfClass(_mapView, @"MKAnnotationContainerView"))
            NSLog(@"tap on the map"); //put your action here
    }
    
    // depth-first search
    UIView *subviewOfKindOfClass(UIView *view, NSString *className)
    {
        static UIView *resultView = nil;
    
        if ([view isKindOfClass:NSClassFromString(className)])
            return view;
    
        for (UIView *subv in [view subviews]) {
            if ((resultView = subviewOfKindOfClass(subv, className)) break;
        }
        return resultView;
    }
    

    It's probably doesn't cover all the edge cases but it seems to work pretty well for me.

    UPDATE (iOS >= 6.0)

    Finally, I found another kind of solution which has the drawback of being valid only for iOS >= 6.0: In fact, this solution exploits the new -(BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer added to the UIViews in this way

    - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
    {
        // overrides the default value (YES) to have gestureRecognizer ignore the view
        return NO; 
    }
    

    I.e., from the iOS 6 onward, it's sufficient to override that UIView method in each view the gesture recognizer should ignore.

提交回复
热议问题