4
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

KIT Developer Advent Calendar 2018

Day 23

swiftで(中心:現在地、半径:現在地と画面タップしたところまでの距離)の円を表示する。

Last updated at Posted at 2018-12-22

初めに

正しくは
中心: 現在地
半径: タップした場所から現在地までの距離
の円を表示させます。
イメージとしては
image.png
タイトルなし.gif
こんな感じです。
画面をタップするごとに円はどんどん上書きされていきます。
自分でアプリを作る際、この円を作る記事がなかったのでまとめます。

プロジェクト作成

まずxcodeでproject作成します。
image.png

image.png
こんな感じで作っていきますプロジェクトネームはなんでもいいです。

mapViewをviewに追加

次はmapViewを表示していきます。
まずframeworkにMapKitを追加します。
image.png
次にcmd+shift+lでmapviewを検索しmainstoryboradにあるviewcontrollerにドラッグします。
image.png
image.png
ここまですると画面にマップが表示されます。

現在地表示

次に現在地を表示していきます。
まずviewControllerにMapkitとCoreLocationをimportします。
さらにmainstoryboradの方のmapViewを紐付けしておきます。やり方は割愛。下の画像のようになっていればokです。ちなみに下の画像を見てもらうと分かりますがクラス継承もしているので忘れずに継承しておきましょう。

viewController.swift
import UIKit
import MapKit
import CoreLocation
class ViewController: UIViewController,CLLocationManagerDelegate,MKMapViewDelegate  {

    @IBOutlet weak var mapView: MKMapView!
    override func viewDidLoad() {
        super.viewDidLoad() 
    }
}

ついでにmainstoryboardの方でuserLocationをONにしておきます。
image.png

次にユーザーに位置情報を使っていいかの許可を取る部分です。
まずinfo.plistに

<key>NSLocationWhenInUseUsageDescription</key>
<string>このアプリで位置情報を使います</string>

を追加します。
次にviewControllerに色々追加します。

import UIKit
import MapKit
import CoreLocation
class ViewController: UIViewController,CLLocationManagerDelegate,MKMapViewDelegate  {
    //追加部分1
    var myLocationManager:CLLocationManager!
    @IBOutlet weak var mapView: MKMapView!
    override func viewDidLoad() {
        super.viewDidLoad()
        //追加部分2
        myLocationManager = CLLocationManager()
        myLocationManager.requestWhenInUseAuthorization()
                mapView.delegate = self
        myLocationManager.delegate = self
    }
    
    //追加部分3
    func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
        print("error")
    }
}

今回は現在地を表示することがメインではないので説明は割愛します。
ついでにデリゲートも追加しています。
ここまでで現在地は表示されているはずです。

円の作成

それでは円を作っていきます。
viewControllerにoverrayメソッドを追加します。
このメソッド内で円を作成してマップ上に追加できるようにします。

func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
        let circle : MKCircleRenderer = MKCircleRenderer(overlay: overlay);
        circle.strokeColor = UIColor.red //円のborderの色
        circle.fillColor = UIColor(red: 0.5, green: 0.0, blue: 0.0, alpha: 0.5)  //円全体の色。今回は赤色
        circle.lineWidth = 1.0 //円のボーダーの太さ。
        return circle
    }

円の表示

それではあとはマップをタップした時の動作

  1. すでに表示されている円の削除
  2. タップ位置と現在地の距離の測定
  3. 円を描写
    をやっていきます
    まずviewDidloadの上に円を格納する変数を宣言します。
    この変数をここで宣言しないとすでにマップに表示されている円が消せなくなります。
viewController.swift
 var mkCircle = MKCircle(center:CLLocationCoordinate2DMake(0.0, 0.0) , radius: 10)//円自体を格納するやつ

次にUITapGestureRecognizerをmainstoryboradのmapViewに追加します。
image.png
さらにviewControllerにUITapGestureRecognizerをctrl + ドラッグしてactionを追加します。
image.png
引数の型をanyからUITapGestureRecognizerにしときましょう。
image.png
最後にmapTappedメソッド内の処理を追加して完成です。

viewController.swift
 @IBAction func mapTapped(_ sender: UITapGestureRecognizer) {
        
        if sender.state == UIGestureRecognizer.State.ended {
            mapView.removeOverlay(mkCircle) //すでにマップ上にある円を削除
            let userCoordinate = mapView.userLocation.coordinate//現在地取得(円の中心)
            let tapPoint: CGPoint = sender.location(in: self.mapView)//タップした座標を取得
            let tap: CLLocationCoordinate2D = self.mapView.convert(tapPoint, toCoordinateFrom: mapView)//タップした座標を型変換
            let tapx = tap.latitude//タップしたとこのx座標格納
            let tapy = tap.longitude//タップしたとこのy座標格納
            let mylocation: CLLocation = CLLocation(latitude: userCoordinate.latitude, longitude: userCoordinate.longitude)//CLLocationに現在地を格納
            let taplocation: CLLocation = CLLocation(latitude: CLLocationDegrees(tapx), longitude: CLLocationDegrees(tapy))//CLLocationにタップしたとこを格納
            let distance = mylocation.distance(from: taplocation)//円の半径(現在地とタップしたとこの距離)を測定
            let circleRadius = CLLocationDistance(distance)//distanceを型変換
            mkCircle = MKCircle(center: userCoordinate, radius:circleRadius)//円の中心と半径を設定
            mapView.addOverlay(mkCircle)//円を描写(さっき書いたメソッドの呼び出し)
        }
    }
image.png 画面タップした時にこんな感じで表示されれば完成です。
4
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?