4

ユーザーがマップをタップすると、MKMap の上にツールバーを表示および非表示にする UITapGestureRecognizer があります。

ただし、ユーザーが MKMapAnnotation をタップすると、マップが通常の方法 (上記) でタップに応答することは望ましくありません。さらに、ユーザーがマップ上の別の場所をタップして MKAnnotation コールアウトの選択を解除した場合にも、ツールバーが応答しないようにします。そのため、ツールバーは、現在選択されている状態の MKAnnotations がない場合にのみ応答する必要があります。また、ユーザーが注釈を直接クリックしたときに応答する必要もありません。

これまでのところ、マップ上のタップ ジェスチャに反応する次のアクションを試していますが、注釈ビューは検出されず (最初の if ステートメント)、このメソッドに関係なく注釈ビューも起動されます。

 -(void)mapViewTapped:(UITapGestureRecognizer *)tgr
{
    CGPoint p = [tgr locationInView:self.mapView];

    UIView *v = [self.mapView hitTest:p withEvent:nil];

    id<MKAnnotation> ann = nil;

    if ([v isKindOfClass:[MKAnnotationView class]])<---- THIS CONDITION IS NEVER MET BUT ANNOTATIONS ARE SELECTED ANYWAY
    {
        //annotation view was tapped, select it…
        ann = ((AircraftAnnotationView *)v).annotation;
        [self.mapView selectAnnotation:ann animated:YES];
    }
    else
    {

        //annotation view was not tapped, deselect if some ann is selected...
        if (self.mapView.selectedAnnotations.count != 0)
        {
            ann = [self.mapView.selectedAnnotations objectAtIndex:0];
            [self.mapView deselectAnnotation:ann animated:YES];
        }

        // If no annotation view is selected currently then assume control of
        // the navigation bar.
        else{

            [self showToolBar:self.navigationController.toolbar.hidden];
        }
    }
}

これを実現するには、注釈呼び出しの起動をプログラムで制御し、タップ イベントがいつ注釈にヒットしたかを検出する必要があります。

どんな助けでも大歓迎です。

4

2 に答える 2

1

次のリンクが非常に役立つと思います。

http://blog.asynchrony.com/2010/09/building-custom-map-annotation-callouts-part-2/

MKAnnotationView をタッチセンシティブにするにはどうすればよいですか?

最初のリンクでは、アノテーションへのタッチの伝播を防ぎ、アノテーションが選択的に応答するようにする方法について説明しています。2 つ目のリンクでは、タッチを検出する方法について説明しています。

于 2013-11-27T16:27:13.130 に答える
0

MKMapAnnotationView は MKMapView の上にあるため、タッチ イベントを取得してそれに応答する (選択される) ので、注釈を手動で選択する必要はないと思います。

その後、Advanced Gesture Recognizer WWDC 2010 ビデオを見ると、MKMapView が注釈ビューの下にある場合でもタップ イベントを受け取ることがわかります。-(void)mapViewTapped:(UITapGestureRecognizer *)tgrそれがおそらくあなたのメソッドが呼び出される理由です。

それとは別に、なぜあなたのif ([v isKindOfClass:[MKAnnotationView class]])ことが決して真実ではないのかわかりません。私は自分のコードでまったく同じことを行い、正常に動作します!

最後に、最後の質問に答えるために、ユーザーがコールアウトを閉じようとしているときに何もしたくない場合は、次のようなカスタム isCalloutOpen ブール値を追跡できます。

- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view {
    //some code
    _isCalloutOpen = YES;
}

- (void)mapView:(MKMapView *)mapView didDeselectAnnotationView:(MKAnnotationView *)view {
    // delay the reset because didDeselectAnnotationView could (and is often) called before your gesture recgnizer handler method get called.
    [self performSelector:@selector(resetCalloutOpenState) withObject:Nil afterDelay:0.1];
}

- (void)resetCalloutOpenState {
    _isCalloutOpen = NO;
}

- (void)mapViewTapped:(UITapGestureRecognizer *)tgr {
    if (_isCalloutOpen) {
        return;
    }
}
于 2013-12-16T15:39:18.747 に答える