Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
321 views
in Technique[技术] by (71.8m points)

ios - MKAnnotationView and tap detection

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

I now want to add a MKAnnotationView to the map. I can tap the annotation and mapView:mapView didSelectAnnotationView:view fires (which is where I'll add additional logic to display a UIView).

The issue is now when I tap the annotation, the MKMapView tap gesture also fires.

Can I set it so if I tap the annotation, it only responds?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...