web-dev-qa-db-ja.com

MKMapView MKPointAnnotationタップイベント

注釈のリストがあります(MKPointAnnotation)。ビュー全体のUIViewController、MKMapViewを実装するController、ユーザーがマップと対話するのを検出するのに役立つと考えているUIViewController、MKPointAnnotationを実装する(サブクラス)Controllerがあり、注釈の表示方法を示します。

ただし、ユーザーによるタップイベントの検出には驚かされます。

グーグルは、次の機能を実装することで何かをしなければならないと言った。

- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control

また、MapViewDelegate(プロトコル)を実装するクラスでこれを実装する必要があります。

しかし、私はすべて混乱しており、前進することができません。誰が何をすべきか教えてもらえますか?

大騒ぎしてすみません!

46
Ravi Vooda

注釈ビューでのユーザーの操作を検出する方法は2つあります。一般的な手法は、MKAnnotationViewのコールアウト(通常のマップアプリでピンをタップしたときに表示される標準の小さなポップオーバーバブル)を定義することです。そして、標準のviewForAnnotationメソッドで注釈の注釈ビューを作成します。

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
{
    if ([annotation isKindOfClass:[MKUserLocation class]])
        return nil;

    MKAnnotationView *annotationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"loc"];
    annotationView.canShowCallout = YES;
    annotationView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];

    return annotationView;
}

これを行うと、吹き出しが表示されますが、正しいアクセサリを追加します。これは、上記の例では開示インジケータです。こうすると、アノテーションビュー(上の例では地図上のピン)をタップしてコールアウトを表示し、そのコールアウトの適切なアクセサリ(この例では小さな開示インジケーター)をタップすると、calloutAccessoryControlTappedが呼び出されます(以下の例では、詳細ビューコントローラーにセグエを実行します)。

- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control
{
    [self performSegueWithIdentifier:@"DetailsIphone" sender:view];
}

これは、小さなiPhone画面での非常に典型的なユーザーエクスペリエンスです。

ただし、そのUXが気に入らず、標準のコールアウトが望ましくないが、何か他のことをしたい場合は、コールアウトが表示されないようにMKAnnotationViewを定義できますが、代わりにインターセプトして何か他の操作を行います(たとえば、iPadマップアプリでは、標準のコールアウトではなく、より洗練されたポップオーバーを表示できます)。たとえば、MKAnnotationViewにコールアウトを表示しないようにすることができます。

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
{
    if ([annotation isKindOfClass:[MKUserLocation class]])
        return nil;

    MKAnnotationView *annotationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"loc"];
    annotationView.canShowCallout = NO;

    return annotationView;
}

しかし、その後、手動でdidSelectAnnotationViewを処理して、ユーザーがMKAnnotationViewをタップしたことを検出できます。この例では、ポップオーバーを示しています。

- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view
{
    [mapView deselectAnnotation:view.annotation animated:YES];

    DetailsViewController *controller = [self.storyboard instantiateViewControllerWithIdentifier:@"DetailsPopover"];
    controller.annotation = view.annotation;
    self.popover = [[UIPopoverController alloc] initWithContentViewController:controller];
    self.popover.delegate = self;
    [self.popover presentPopoverFromRect:view.frame
                                  inView:view.superview
                permittedArrowDirections:UIPopoverArrowDirectionAny
                                animated:YES];
}

my answer here に、上記のコードによって生成されたユーザーインターフェイスの画面スナップショットをいくつか含めます。

104
Rob

Swift 3:のロブの例:

class MapViewController: UIViewController
{
    override func viewDidLoad()
    {
        super.viewDidLoad()

        // Create map view in storyboard
        view.delegate = self
    }
}

extension MapViewController: MKMapViewDelegate
{
    func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView?
    {
        let annotationView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: "annotationView")
        annotationView.canShowCallout = true
        annotationView.rightCalloutAccessoryView = UIButton.init(type: UIButtonType.detailDisclosure)

        return annotationView
    }

    func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl)
    {
        guard let annotation = view.annotation else
        {
            return
        }

        let urlString = "http://maps.Apple.com/?sll=\(annotation.coordinate.latitude),\(annotation.coordinate.longitude)"
        guard let url = URL(string: urlString) else
        {
            return
        }

        UIApplication.shared.openURL(url)
    }
}
8
RhodanV5500

このメソッドの追加ボタン

-(MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation 
{
  pinView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
  pinView.canShowCallout = YES;
}

Then callout method
- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control
{
      InfoView *infoView = [[InfoView alloc]initWithNibName:@"InfoView" bundle:nil];
        [self.navigationController pushViewController:infoView animated:YES];

} 
5
Bajaj