Help us understand the problem. What is going on with this article?

MKMapViewでタップした位置に円を描く(Swift 4対応)

More than 1 year has passed since last update.

すでに地図(MKMapView)は配置済みであることを想定しています。

UITapGestureRecognizer登録

地図がタップされたことを検出するために UITapGestureRecognizer を登録します。

コードで登録することもできますが、今回はStoryBoardを使いました。「Tap Gesture Recognizer」を MKMapView にドラッグします。

スクリーンショット 2014-11-15 22.27.55.png

「Sent Actions」にタップ時に実行されるメソッド名をセットしておきます。

スクリーンショット 2014-11-15 22.37.43.png

今回は mapViewDidTap というメソッドを用意しました。

- (IBAction)mapViewDidTap:(UITapGestureRecognizer *)sender
{
    if (sender.state == UIGestureRecognizerStateEnded)
    {
        // タップした位置を緯度経度に変換してサークルを表示
        CGPoint tapPoint = [sender locationInView:self.view];
        CLLocationCoordinate2D center = [self.mapView convertPoint:tapPoint
                                              toCoordinateFromView:self.mapView];
        MKCircle *circle = [MKCircle circleWithCenterCoordinate:center
                                                         radius:100]; // 半径100m
        [self.mapView addOverlay:circle];
    }
}

Swift

@IBAction func mapViewDidTap(sender: UITapGestureRecognizer) {
    if sender.state == UIGestureRecognizerState.ended {
        let tapPoint = sender.location(in: view)
        let center = mapView.convert(tapPoint, toCoordinateFrom: mapView)
        let circle = MKCircle(center: center, radius: 100)
        mapView.add(circle)
    }
}

タップされた画面上の座標を locationInView で取得し、それを convertPoint で緯度経度に変換しているのがポイントです。

その緯度経度を元に MKCircle で円を作り、addOverlay で地図に円を表示します。

円の色などを設定

円が表示される際に次のデリゲートが呼ばれるので、この中で円の色などを指定します。(MKMapViewのdelegateを指定しないと呼ばれません)

- (MKOverlayRenderer *)mapView:(MKMapView *)mapView
            rendererForOverlay:(id <MKOverlay>)overlay
{
    if ([overlay isKindOfClass:[MKCircle class]])
    {
        MKCircleRenderer *renderer =
        [[MKCircleRenderer alloc] initWithCircle:(MKCircle *)overlay];
        renderer.strokeColor = [UIColor redColor]; // 外側の線の色
        renderer.fillColor = [[UIColor redColor] colorWithAlphaComponent:0.4]; // 内側を塗りつぶす色
        renderer.lineWidth = 1; // 外側の線の太さ

        return renderer;
    }

    return nil;
}

Swift

func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
    let circleRenderer : MKCircleRenderer = MKCircleRenderer(overlay: overlay);
    circleRenderer.strokeColor = UIColor.red
    circleRenderer.fillColor = UIColor(red: 0.0, green: 0.0, blue: 0.7, alpha: 0.5)
    circleRenderer.lineWidth = 1.0
    return circleRenderer
}

実行結果

FullSizeRender 2.jpg

koogawa
ドラムも叩けるプログラマです。iPhoneアプリ、Androidアプリ、mixiアプリを仕事/趣味で作ってます。主な作品 → http://bit.ly/koogawa
http://d.hatena.ne.jp/koogawa/
alu-inc
アルは、マンガファンがもっとマンガを楽しめるサービスを作るために立ち上げられた、テクノロジー企業です。
https://alu.jp
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away