SwiftUI Mapkitを触る

2023年6月 WWDC2023にてMapKitが大幅に拡張されました。SwiftUIを使うことで簡単に地図アプリを作成できるとのことなので触ってみました。

Mapの表示

MapKitをinportしてMap()で表示できます。

import SwiftUI
import MapKit

struct ContentView: View {
  var body: some View {
    Map()
  }
}


mapStyle()を付与することで地図の見た目を変化させられます

Map().mapStyle(.imagery(elevation: .realistic))

他のもたくさんスタイルがあります

マップにマーカー、アノテーションを表示させる

・マーカー

Markerで表示ができます

extension CLLocationCoordinate2D{
   static let oosaka = CLLocationCoordinate2D(latitude: 34.703124622680484,longitude:135.4960062127632 )
}

struct ContentView: View {
  var body: some View {
   Map{
    Marker("大阪駅",systemImage: "train.side.rear.car",coordinate: .oosaka)
   }.mapStyle(.imagery(elevation: .realistic))
  }
}

座標はGoogleMapで調べました

・アノテーション

Viewなどを設定できます

Annotation("大阪",coordinate: .oosaka,anchor: .bottom){
  VStack{
     Image(systemName: "train.side.rear.car")
     Text("大阪駅")
  }
  .padding(10)
  .foregroundStyle(.white)
  .background(Color.blue)
  .cornerRadius(10)
}

他にもMapCircleなどがあります

 MapCircle(center: .oosaka, radius: 100)
.foregroundStyle(.indigo.opacity(0.5))

検索について

MKLocalSearch.Request()で検索ができます

struct ContentView: View {
@State private var searchResults:[MKMapItem] = []
  var body: some View {
   Map{
    Marker("大阪駅",systemImage: "train.side.rear.car",coordinate: .oosaka)
    MapCircle(center: .oosaka, radius: 100)
    .foregroundStyle(.indigo.opacity(0.5))

    ForEach(searchResults, id: \.self) {result in
      Marker(item: result)
    }
   }
   .mapStyle(.imagery(elevation: .realistic))
   .safeAreaInset(edge: .bottom)
    {
     HStack {
      Spacer()
      ButtonView(searchResults: $searchResults)
      Spacer()
     }
    .background(.thinMaterial)
    }
  }
}

struct ButtonView: View{
 @Binding var searchResults:[MKMapItem]
 var body: some View {
  Button {
   search(for:"playground")
  } label: {
   Label("Playgrounds",systemImage: "figure.stand")
  }
 }
 func search(for query: String){
  let request = MKLocalSearch.Request()
  request.naturalLanguageQuery = query
  request.resultTypes = .pointOfInterest
  request.region = MKCoordinateRegion(
  center: .oosaka, span: MKCoordinateSpan(latitudeDelta: 0 , longitudeDelta: 0 ))
   Task {
    let search = MKLocalSearch(request: request)
    let response = try? await search.start()
    searchResults = response?.mapItems ?? []
   }
 }
}

簡単に実装ができるので面白いですね
緯度経度あれば簡単に地図アプリが開発できそうでした
APIとか駆使して作ってみたいですね

Related Post