Swift5.1.3 Xcode11.3 SwiftUI
- マップアプリ上に複数のピン留めを作ります
- Annotationでメモを地図上に記入します
- SwiftUIのMapKitで自作アプリを作成します
「以下は動画のハイライトです。」
地図上に複数のピン留めを加えることで重要な地点ごとにメモを取ることが可能です。兄妹の住まいなどを例に解説しておりますが、メモの箇所を変えて自分の好みの観光名所など入れてみてください。
SwiftUIはコードであればコピペですぐアプリを作ることができます。初心者の方にとってはありがたいですね。地図は2本指でドラッグしたり拡大することも可能です。自分の好みの名所の周りにどういうものがあるのか確認するのも新しい発見があって面白いですね。
今回使うのは以下のライブラリです。
import MapKit
では早速、名所の緯度経度の情報をネットなどで入手してください。
ここではイギリス、日本、中国の適当な地点を緯度(latitude), 経度(longitude)に入れております。
@State var count = 0
@State var homeTowns: [HomeTown] = [
HomeTown(name: "UK My", location: .init(latitude: 51.1, longitude:
0.2)),
HomeTown(name: "JP Sister's", location: .init(latitude: 36.2,
longitude: 140.1)),
HomeTown(name: "CH Brother's", location: .init(latitude: 32.5,
longitude: 117.8))
]
例として三つあげておりますが、これ以上の複数地点の入力も可能です。次に二つのstructを入力します。HomeTownはデータ形式のために、MapViewはマップのデザインに使用します。
struct HomeTown {
let name: String
let location: CLLocationCoordinate2D
}
struct MapView: UIViewRepresentable {
@Binding var homeTowns: [HomeTown]
@State var cou:Int
func makeUIView(context: Context) -> MKMapView {
let map = MKMapView()
return map
}
func updateUIView(_ mView: MKMapView, context: Context) {
let locValue = homeTowns[cou].location
let coordinate = CLLocationCoordinate2D(latitude: locValue.latitude, longitude:
locValue.longitude)
let span = MKCoordinateSpan(latitudeDelta: 2.0, longitudeDelta: 2.0)
let region = MKCoordinateRegion(center: coordinate, span: span)
mView.setRegion(region, animated: true)
let annotation = MKPointAnnotation()
annotation.coordinate = locValue
annotation.title = homeTowns[cou].name
annotation.subtitle = "Home"
mView.addAnnotation(annotation)
}
}
この中で以下が地図を表示するのに重要な箇所です。
let locValue = homeTowns[cou].location
let coordinate = CLLocationCoordinate2D(latitude: locValue.latitude, longitude:
locValue.longitude)
let span = MKCoordinateSpan(latitudeDelta: 2.0, longitudeDelta: 2.0)
let region = MKCoordinateRegion(center: coordinate, span: span)
mView.setRegion(region, animated: true)
引数にlatitudeとlongitudeがありますがこの数値を変えることで表示する地図のポイントを変えることが可能となります。
一方、ピン留めする箇所は以下です。
let annotation = MKPointAnnotation()
annotation.coordinate = locValue
annotation.title = homeTowns[cou].name
annotation.subtitle = "Home"
mView.addAnnotation(annotation)
AnnotationのTitleに文字を入力することが可能なのでここにメモを取ることができます。Subtitleも入力することが可能で、ピンをタップするとSubtitleの方もマップ上に表示されるようになります。
これらを利用してContentView内に以下を入れます。
var body: some View {
ZStack {
if count == 0 {
MapView(homeTowns: $homeTowns, cou: count)
.edgesIgnoringSafeArea(.vertical)
} else if count == 1 {
MapView(homeTowns: $homeTowns, cou: count)
.edgesIgnoringSafeArea(.vertical)
} else {
MapView(homeTowns: $homeTowns, cou: count)
.edgesIgnoringSafeArea(.vertical)
}
VStack {
Spacer()
Button(action: {
self.count += 1
self.count = self.count%3
print("cou", self.count)
}) {
Text("Next")
.padding(.bottom)
}
}
}
}
地図の最下部に「Next」というボタンがあります。ここを押すことでお気に入りの次の地点にジャンプすることができるようになります。配置は地図上に浮上するようにZStackを使用します。構造体の更新は厳しいのでデータ分の数だけ以下作る必要があります。この箇所はちょっと初心者っぽい書き方です。
if count == 0 {
MapView(homeTowns: $homeTowns, cou: count)
.edgesIgnoringSafeArea(.vertical)
} else if count == 1 {
MapView(homeTowns: $homeTowns, cou: count)
.edgesIgnoringSafeArea(.vertical)
} else {
MapView(homeTowns: $homeTowns, cou: count)
.edgesIgnoringSafeArea(.vertical)
}
私の調べたところによると$0やfilter, mapなどを駆使してカッコよく書く方法も発見したのですが、初心者の方にはとても理解できるようなコードではなかったためこちらにさせていただきました。3つぐらいの少数地点であればこの書き方でもコード量があまり変わらなかったところもございます。
ソースコードはYouTubeのコメント欄に記載します。
目次へ戻る