初めに
正しくは
中心: 現在地
半径: タップした場所から現在地までの距離
の円を表示させます。
イメージとしては
こんな感じです。
画面をタップするごとに円はどんどん上書きされていきます。
自分でアプリを作る際、この円を作る記事がなかったのでまとめます。
プロジェクト作成
こんな感じで作っていきますプロジェクトネームはなんでもいいです。
mapViewをviewに追加
次はmapViewを表示していきます。
まずframeworkにMapKitを追加します。
次にcmd+shift+lでmapviewを検索しmainstoryboradにあるviewcontrollerにドラッグします。
ここまですると画面にマップが表示されます。
現在地表示
次に現在地を表示していきます。
まずviewControllerにMapkitとCoreLocationをimportします。
さらにmainstoryboradの方のmapViewを紐付けしておきます。やり方は割愛。下の画像のようになっていればokです。ちなみに下の画像を見てもらうと分かりますがクラス継承もしているので忘れずに継承しておきましょう。
import UIKit
import MapKit
import CoreLocation
class ViewController: UIViewController,CLLocationManagerDelegate,MKMapViewDelegate {
@IBOutlet weak var mapView: MKMapView!
override func viewDidLoad() {
super.viewDidLoad()
}
}
ついでにmainstoryboardの方でuserLocationをONにしておきます。
次にユーザーに位置情報を使っていいかの許可を取る部分です。
まず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
}
円の表示
それではあとはマップをタップした時の動作
- すでに表示されている円の削除
- タップ位置と現在地の距離の測定
- 円を描写
をやっていきます
まずviewDidloadの上に円を格納する変数を宣言します。
この変数をここで宣言しないとすでにマップに表示されている円が消せなくなります。
var mkCircle = MKCircle(center:CLLocationCoordinate2DMake(0.0, 0.0) , radius: 10)//円自体を格納するやつ
次にUITapGestureRecognizerをmainstoryboradのmapViewに追加します。
さらにviewControllerにUITapGestureRecognizerをctrl + ドラッグしてactionを追加します。
引数の型をanyからUITapGestureRecognizerにしときましょう。
最後にmapTappedメソッド内の処理を追加して完成です。
@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)//円を描写(さっき書いたメソッドの呼び出し)
}
}