【iphoneアプリ開発_初心者必見】地図を表示してみよう!! (MapKitの基礎・基本)
最終更新日:2020年08月14日
家に引きこもっている「ゴルトン社長」です。(twitter : @GoRuton_1stStep)
地図を表示してみよう!! (MapKitの基礎・基本)
- 地図アプリは単に地図として使われたり,他の機能と組み合わせて使うなど様々な用途があります
- ここでは基本的な現在地の位置情報を示す地図アプリを作成してみましょう
人気の記事!
人生を変えたい人に向けて「はじめの一歩」を踏み出したい人にオススメ!
www.goruton.com www.goruton.com www.goruton.com www.goruton.com
1) フレームワークの導入
MapKitとCoreLocationの2つのフレームワークを導入します
- Map(プロジェクト名) を選択
- TARGETS (Map) を選択
- 右上の Build Phases を選択
- 4つの▶で始まる項目が表示される
- Link Binary With Libraries のところの▶をクリックして展開
- +マークを押してください。
- MapKit と入力して検索
- MapKit.framework という名前のフレームワークが表示されるので、それを選択してAdd!
- 同じ手順で CoreLocation.framework もAddしてください。
2) 位置情報の利用の許可のリクエストの実装と現在地の表示
- 現在地を取得、表示するためにユーザーに位置情報の利用の許可をリクエストする必要があります。
- この機能を実装し、ユーザーに許可をもらえないと現在地の取得、表示はできません。
- Xcodeの画面の一番左のファイルの階層などを表しているところの info.plist にカーソルを合わせ右クリック(副クリック), OpenAs ▶SourceCode を選択してください。
- プロパティリストがソースコードで表示されます。
- dict のタグで囲まれなかに key として NSLocationWhenInUseUsageDescriptionを、Stringには任意の文字列を以下のように入れます
info.plist
<plist version="1.0"> <dict> //省略 <key>NSLocationWhenInUseUsageDescription</key> <string>位置情報をこのアプリの起動時に使います</string> </dict> </plist>
3)実際のコードと実装
はじめにストーリーボードにMapViewを配置して、配置したMapViewをコードと紐付けし,画面いっぱいに広げてください
その後,ViewController.swiftに下記のように記述してください
ViewController.swift
import UIKit import MapKit import CoreLocation class ViewController: UIViewController, CLLocationManagerDelegate{ @IBOutlet weak var testMapView: MKMapView! //CLLocationManagerの入れ物を用意 var myLocationManager:CLLocationManager! override func viewDidLoad() { super.viewDidLoad() //CLLocationManagerをインスタンス化 myLocationManager = CLLocationManager() //位置情報使用許可のリクエストを表示するメソッドの呼び出し myLocationManager.requestWhenInUseAuthorization() } //位置情報取得に失敗したときに呼び出されるメソッド func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) { print("error") } }
- class ViewController:UIViewController に続けて,CLLocationManagerDelegate を追記します。
- CLLocationManagerDelegate には許可のステータスが変更されたときに呼び出されるメソッドが定義されています。
- このメソッドをViewController実装することで変更後の許可のステータスを受け取ることができます。
- MapViewを紐付けしたところの下にCLLocationManagerの入れ物を定義します。
- viewdidloadの中でCLLocationManagerをインスタンス化することでCLLocationManagerに含まれるメソッドを使えるようにします。
- その次にCLLocationManagerのメソッドのひとつのrequestWhenInUseAuthorization()を呼び出します。
- この記述をすることでアプリ使用時の位置情報の利用の許可をユーザーにリクエストできます。
- 画面左のMain.storyboardを選択
- 画面右側のShow the Attributes inspectorを選択
- User Locationのチェックを入れる
- command+Rで実装して,画像のようになっているか確認してください
目次2
位置情報の表示アプリの作成
1)特定の位置を表示 2)ピンの様々な表示方法
1)特定の位置を表示
- ViewController.swiftに下記のコードを記述してください
ViewController.swift
import UIKit import MapKit import CoreLocation class ViewController: UIViewController, CLLocationManagerDelegate{ @IBOutlet weak var mapView: MKMapView! //CLLocationManagerの入れ物を用意 var myLocationManager:CLLocationManager! override func viewDidLoad() { super.viewDidLoad() /*アップル本社周辺(緯度37.331652997806785, 経度-122.03072304117417)を表示*/ let coordinate = CLLocationCoordinate2DMake(37.331652997806785, -122.03072304117417) let span = MKCoordinateSpan(latitudeDelta: 0.01, longitudeDelta: 0.01) let region = MKCoordinateRegion(center: coordinate, span: span) mapView.setRegion(region, animated:true) } //位置情報取得に失敗したときに呼び出されるメソッド func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) { print("error") } }
- 表示したい位置を CLLocationCoordinate2DMake メソッドで指定
- 今回はアップル本社周辺(緯度37.331652997806785, 経度-122.03072304117417)を表示
- 表示する範囲を MKCoordinateSpanMake メソッドで指定
- 数値が小さくなるほど表示される領域は狭くなります。(ズームレベルが高くなる)
- 「位置」と「表示範囲」から Region オブジェクトを生成し、MapViewにセット
- command+Rで実装して,アップル本社周辺が表示されたか確認してください
2)ピンの様々な表示方法
- 地図上にピンを表示していきます。
- このパートで使用する全体のサンプルコードを以下に示します
ViewController.swift
import UIKit import MapKit class ViewController: UIViewController, MKMapViewDelegate { @IBOutlet weak var mapView: MKMapView! override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. let coordinate = CLLocationCoordinate2DMake(37.331652997806785, -122.03072304117417) let span = MKCoordinateSpan.init(latitudeDelta: 0.003, longitudeDelta: 0.003) let region = MKCoordinateRegion.init(center: coordinate, span: span) mapView.setRegion(region, animated:true) // ピンを表示する タイトルを指定する let annotation = MKPointAnnotation() annotation.coordinate = coordinate annotation.title = "title" annotation.subtitle = "subtitle" self.mapView.addAnnotation(annotation) } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } // MARK: - MKMapView delegate // Called when the region displayed by the map view is about to change func mapView(_ mapView: MKMapView, regionWillChangeAnimated animated: Bool) { print(#function) } // Called when the annotation was added //ピンにアニメーションをつける func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? { if annotation is MKUserLocation { return nil } let reuseId = "pin" var pinView = mapView.dequeueReusableAnnotationView(withIdentifier: reuseId) as? MKPinAnnotationView if pinView == nil { pinView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: reuseId) pinView?.animatesDrop = true pinView?.canShowCallout = true pinView?.isDraggable = true //ピンに色を表示する pinView?.pinColor = .purple let rightButton: AnyObject! = UIButton(type: UIButton.ButtonType.detailDisclosure) pinView?.rightCalloutAccessoryView = rightButton as? UIView } else { pinView?.annotation = annotation } return pinView } //バルーンにボタンをつけてみる func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) { print(#function) if control == view.rightCalloutAccessoryView { performSegue(withIdentifier: "toTheMoon", sender: self) } } func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, didChange newState: MKAnnotationView.DragState, fromOldState oldState: MKAnnotationView.DragState) { if newState == MKAnnotationView.DragState.ending { let droppedAt = view.annotation?.coordinate print(droppedAt.debugDescription) } } // MARK: - Navigation @IBAction func didReturnToMapViewController(_ segue: UIStoryboardSegue) { print(#function) } }
ピンを表示する, ピンのタイトルを指定する
- 地図上にピンを表示するため,MKPointAnnotation オブジェクトを使用
- coordinate プロパティにピンを表示する緯度経度を指定
- MapView に addAnnotation メソッドで追加
- MKPointAnnotation クラスはプロパティに title と subtitle を持っている
- 文字列を指定することで、ピンをタップした時にタイトルを表示するバルーンを出すことが可能
let annotation = MKPointAnnotation() annotation.coordinate = coordinate annotation.title = "title" annotation.subtitle = "subtitle" self.mapView.addAnnotation(annotation)
ピンにアニメーションを付ける
ピンが上から降ってくるようにしてみます。
- MapView のデリゲートを ViewController.swift にセットします。
- Story Board で MapView を選択
- 画面右側の「Connections Inspector」にある delegate の ○ と、画面左側の View Controller をドラッグアンドドロップで結びつけます。
- MapView のデリゲートメソッドを実装していきます。
- クラス宣言部に MKMapViewDelegate を追記します。
class ViewController: UIViewController, MKMapViewDelegate { =========== func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView? { if annotation is MKUserLocation { return nil } let reuseId = "pin" var pinView = mapView.dequeueReusableAnnotationViewWithIdentifier(reuseId) as? MKPinAnnotationView if pinView == nil { pinView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: reuseId) pinView?.animatesDrop = true } else { pinView?.annotation = annotation } return pinView }
- viewForAnnotation デリゲートメソッドを実装します。
- このメソッドはピンが画面に表示する直前に呼ばれ、今から表示するピンの属性や外観などをMKPinAnnotationView オブジェクトを使って指定することができます。
- ピンは何度も再利用されます(UITableViewCell のようなイメージ)。
- dequeueReusableAnnotationViewWithIdentifier で再利用できるピンを取り出します。
- 再利用できるものがなければ新たに作成します。
- アニメーションを付けるには animatesDrop プロパティに true を指定します。
ピンの色を変更する
- ピンの色はデフォルトで赤
- MKPinAnnotationView の pinTintColor プロパティをセットすることで好きな色に変更できます。
pinView?.pinColor = .purple
バルーンにボタンを付けてみる
- バルーンに UIButton を付けることもできます。
- MKPinAnnotationView の canShowCallout プロパティを true にセットします。
- これをやらないとバルーンが表示されないので注意してください。
pinView?.canShowCallout = true let rightButton: AnyObject! = UIButton(type: UIButtonType.DetailDisclosure) pinView?.rightCalloutAccessoryView = rightButton as? UIView
- ボタンがタップされると calloutAccessoryControlTapped デリゲートが呼ばれます。
- ここに必要な処理を書いていくと良いでしょう。
func mapView(mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) { print(__FUNCTION__) }
参考リンク
最後に!!
最後までご覧いただき、本当にありがとうございます!!
最近は、たくさんの読者さんから「コメント」や「メッセージ」が届くようになりました!!
皆さんと会話できて嬉しいですし、コメントで毎日励まされています。
ありがとうございます!
これからも、ゴルトン社長は「毎日」ブログを更新しています! www.goruton.com www.goruton.com www.goruton.com www.goruton.com www.goruton.com
皆さんから人気がある記事
www.goruton.com www.goruton.com www.goruton.com www.goruton.com www.goruton.com
まとめ記事
www.goruton.com www.goruton.com www.goruton.com www.goruton.com www.goruton.com www.goruton.com www.goruton.com