Edited at

MkMapViewの使い方(swift版)

More than 1 year has passed since last update.

MkMapViewを使って地図系アプリを作っているのですが、意外にまとまった情報がありませんでした。そこで簡単な地図アプリ作成手順として情報を整理しました。

作成したアプリは、Githubに置いています。


機能

以下の機能を実装しました。

* 現在位置を地図上に表示できる

* 緯度経度をラベル表示できる

* 現在位置のトラッキングを開始・終了できる

* 地図のスケールを自動的に調整できる

* 現在位置にピンをつけることができる

* ピンのコールアウトをタップしないで表示する


アプリ作成手順


  1. プロジェクト作成

  2. アプリで位置情報を使うための設定

  3. 位置情報取得処理追加

  4. ピン表示処理追加


プロジェクト作成

ここを参考にして、プロジェクトを作成します。


  • Single View Applicationを選択してプロジェクトを作成します。

  • 地図ライブラリ(MapKit.framework)を追加します。

  • Storyboardを使ってMap Kit Viewを追加します。

位置情報表示のためのラベルと位置情報取得開始・終了用ボタンを追加しています。


アプリで位置情報を使うための設定

位置情報を使うための以下のキーをinfo.plistに追加します。

* Privacy - Location When In Use Usage Description

* Privacy - Location Always Usage Description

アプリ初回起動時にユーザーに許可を出す時のメッセージになります。

        // 位置情報取得時に、リクエストを出すと

locationManager!.requestWhenInUseAuthorization()

// このメソッドが呼ばれます
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
switch status {
case .notDetermined:
manager.requestWhenInUseAuthorization()
case .restricted, .denied:
break
case .authorizedAlways, .authorizedWhenInUse:
break
}
}

写真 2016-12-31 7 57 04.png


位置情報取得処理追加

 CLLocationManagerクラスを使って位置情報の取得します。

  


開始

startUpdatingLocationを実行します。

位置情報が更新された場合には、CLLocationManagerDelegateプロトコルのlocationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation])が呼ばれます。

    @IBAction func tapStartButton(_ sender: UIButton) {

if locationManager != nil { return }
locationManager = CLLocationManager()
locationManager!.delegate = self
locationManager!.requestWhenInUseAuthorization()

if CLLocationManager.locationServicesEnabled() {
locationManager!.startUpdatingLocation()
}
// tracking user location
mapView.userTrackingMode = MKUserTrackingMode.followWithHeading
mapView.showsUserLocation = true

}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
guard let newLocation = locations.last else {
return
}

let location:CLLocationCoordinate2D
= CLLocationCoordinate2DMake(newLocation.coordinate.latitude, newLocation.coordinate.longitude)
let latitude = "".appendingFormat("%.4f", location.latitude)
let longitude = "".appendingFormat("%.4f", location.longitude)
latLabel.text = "latitude: " + latitude
lngLabel.text = "longitude: " + longitude

// update annotation
mapView.removeAnnotations(mapView.annotations)

let annotation = MKPointAnnotation()
annotation.coordinate = newLocation.coordinate
mapView.addAnnotation(annotation)
mapView.selectAnnotation(annotation, animated: true)

// Showing annotation zooms the map automatically.
mapView.showAnnotations(mapView.annotations, animated: true)

}


終了

stopUpdatingLocationを実行します。

        guard let manager = locationManager else { return }

manager.stopUpdatingLocation()
manager.delegate = nil
locationManager = nil
latLabel.text = "latitude: "
lngLabel.text = "longitude: "

// untracking user location
mapView.userTrackingMode = MKUserTrackingMode.none
mapView.showsUserLocation = false
mapView.removeAnnotations(mapView.annotations)


ピン表示

ピン表示にはMKPointAnnotationクラスを使います。

現在位置を一つだけ表示するために、全削除して追加しています。

        mapView.removeAnnotations(mapView.annotations)

let annotation = MKPointAnnotation()
annotation.coordinate = newLocation.coordinate
mapView.addAnnotation(annotation)
mapView.selectAnnotation(annotation, animated: true)

mapView.showAnnotations(mapView.annotations, animated: true)


開始ボタンタップする前

初期表示は日本がすべて表示されます。

写真 2016-12-31 7 59 08.png

全部のピンを表示してくれます。

開始ボタンをタップ時にmapView.showAnnotationsを実行するとすべてのピンが表示されます。

mapView.setRegionを使ってズーム率を指定することができます。

        var region:MKCoordinateRegion = mapView.region

region.center = location
region.span.latitudeDelta = 0.02
region.span.longitudeDelta = 0.02

mapView.setRegion(region,animated:true)

また、mapView.selectAnnotationとすると引数で渡したピンのコールアウトを表示します。

SimpleMap.png


参考