9

私は持っていMKMapViewます。ワンタップで を追加しましたUITapGestureRecognizer

マップに を追加したいと思いMKAnnotationViewます。注釈をタップして起動できmapView:mapView didSelectAnnotationView:viewます (ここで、UIView を表示するロジックを追加します)。

問題は、注釈をタップすると、MKMapViewタップ ジェスチャも起動することです。

注釈をタップすると反応するだけに設定できますか?

4

6 に答える 6

6

もっときれいな解決策があるかもしれませんが、トリックを行う 1 つの方法は hitTest:withEvent:、タップ ジェスチャ認識セレクターを利用することです。

タップ ジェスチャ レコグナイザを_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;
}

おそらくすべてのエッジケースをカバーしているわけではありませんが、私にとってはうまく機能しているようです。

更新 (iOS >= 6.0)

最後に、 iOS >= 6.0でのみ有効であるという欠点を持つ別の種類のソリューションを見つけ-(BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizerましUIViewた。

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

つまり、iOS 6 以降ではUIView、ジェスチャ レコグナイザーが無視する各ビューでそのメソッドをオーバーライドするだけで十分です。

于 2013-06-20T00:19:55.827 に答える
4

あなたのソリューションは- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch、デリゲートのメソッドを利用する必要があります。

このメソッドでは、タッチが注釈の 1 つにあったかどうかを確認できreturn NOますgestureRecognizer

目的 C:

- (NSArray*)getTappedAnnotations:(UITouch*)touch
{
    NSMutableArray* tappedAnnotations = [NSMutableArray array];
    for(id<MKAnnotation> annotation in self.mapView.annotations) {
        MKAnnotationView* view = [self.mapView viewForAnnotation:annotation];
        CGPoint location = [touch locationInView:view];
        if(CGRectContainsPoint(view.bounds, location)) {
            [tappedAnnotations addObject:view];
        }
    }
    return tappedAnnotations;
}

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
    return [self getTappedAnnotations:touch].count > 0;
}

迅速:

private func getTappedAnnotations(touch touch: UITouch) -> [MKAnnotationView] {
    var tappedAnnotations: [MKAnnotationView] = []
    for annotation in self.mapView.annotations {
        if let annotationView: MKAnnotationView = self.mapView.viewForAnnotation(annotation) {
            let annotationPoint = touch.locationInView(annotationView)
            if CGRectContainsPoint(annotationView.bounds, annotationPoint) {
                tappedAnnotations.append(annotationView)
            }
        }
    }
    return tappedAnnotations
}

func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldReceiveTouch touch: UITouch) -> Bool {
    return self.getTappedAnnotations(touch: touch).count > 0
}
于 2016-01-04T13:51:50.367 に答える
-1

UITapGestureRecognizerプレーン テキストでこれを言っているのは、マップのマルチタッチ機能を台無しにすることを明らかに暗示しているため、マップ ビューに表示する理由がわかりません。

cancelsTouchesInViewのプロパティを見て遊んでみることをお勧めしますUIGestureRecognizer(ドキュメントを参照)。これで問題を解決できると思います。ドキュメントを確認してください。

于 2013-06-19T21:36:05.140 に答える