見出し画像

【Swift】SwiftUIのMapコントロールで指定した場所にピンを表示する

こんにちは。ラフアンドレディ(株)iOS大好き 春蔵です。

今回は地図系アプリでよくある、テキスト入力された場所をもとに地図上にピンを表示する機能をご紹介します。

地図についてはSwiftUIの標準コントールであるMapを使用。
入力された場所の座標の取得は、別記事で紹介しているため省略します。

サンプルコードについては最後にリンクを記載しています。

サンプル画面

地図の表示

       /// 地図表示
        /// interactionModes : ユーザー操作の許可 .pan スワイプ(ドラッグ)による操作を許可。 .zoom ダブルタッチ or ピンチ操作による拡大・縮小の操作を許可 .all .pan と .zoom の両方を許可します。
        /// showsUserLocation : ユーザーの現在位置を表示
        /// userTrackingMode : .follow ユーザーの追跡 .none ユーザーの追跡を停止します。
        /// annotationItems: RandomAccessCollection
        /// annotationContent: : MapMarker  MapPin
        Map(coordinateRegion: $viewModel.region
            ,interactionModes: .all
            ,showsUserLocation: false
            ,userTrackingMode: .none
            ,annotationItems: viewModel.pinItems
            ,annotationContent: { item in
            // 円を表示する
//            MapAnnotation(
//                coordinate: item.coordinate,
//                anchorPoint: CGPoint(x: 0.5, y: 0.5)
//            ) {
//                Circle()
//                    .strokeBorder(Color.blue,lineWidth: 3)
//                    .background(Circle().foregroundColor(Color.blue.opacity(0.2)))
//                    .frame(width: geometry.size.width * 0.8, height: geometry.size.width * 0.8)
//            }
            // ピンを表示する
            MapMarker(coordinate: item.coordinate , tint: .blue)
            }
        )
        .frame(width: geometry.size.width * 0.9, height: geometry.size.width * 0.9)
        .cornerRadius(5)
        .overlay(
            RoundedRectangle(cornerRadius: 5)
                .stroke(Color.primary.opacity(0.8), lineWidth: 0.3)
        )

SwiftUIの標準コントロールであるMap(iOS 14.0〜)を使用し地図を表示します。

この内、大事なパラメータとして、

  • coordinateRegion ・・・ 地図の中心点を緯度、経度で指定します。

  • annotationItems ・・・ 地図上にピンや円等を表示したい場合、緯度、経度で配列指定します。

  • annotationContent  ・・・  地図上に表示するピンや円等の表示方法を指定します。サンプルではピンを指定、コメントアウトされてるコードでは円を指定しています。

指定した場所の座標取得、地図に表示

   /// ピンの設定
    func setPin(){
        /// 縮尺(1度=111km , 1/111 = 1kmの縮尺)
        let span:CLLocationDegrees = 1/111

        // 検索結果クリア
        completions = []
        
        // 検索条件設定
        let request = MKLocalSearch.Request()
        request.naturalLanguageQuery = self.location
        
        // 検索実行
        MKLocalSearch(request: request).start { (response, error) in
            if let placemark = response?.mapItems.first?.placemark {
                DispatchQueue.main.async {
                    // 経度、緯度取得
                    let latitude = placemark.location?.coordinate.latitude ?? 0.0
                    let longitude = placemark.location?.coordinate.longitude ?? 0.0
                    
                    // マップの中心を設定
                    self.region = MKCoordinateRegion(
                        center: CLLocationCoordinate2D(latitude: latitude, longitude: longitude)
                        , span: MKCoordinateSpan(latitudeDelta: span, longitudeDelta: span))

                    // ピン設定
                    self.pinItems = [PinItem(coordinate: .init(latitude: latitude, longitude: longitude))]
                }
            }
        }
    }

入力された場所に関する緯度、経度情報を取得し、Mapコントロールに渡すパラメータを設定します。
self.regionにMapの中心点を座標で指定するとともに、地図の縮尺を指定します。単位は度で1度が約111kmになるため、1/111を指定した場合、地図の縮尺は約1kmです。
self.pinItemsにMap上に表示するピンを座標指定します。複数ある場合は、pinItems内で複数指定します。

コードサンプル

今回紹介したサンプルの全コードです

アプリケーション

今回紹介したMapKitの技術を利用したiOSアプリです。

それではまた!楽しいSwiftライフを!

春蔵のSwift講座


───-- - - - 

フォロー Me!
↓ ↓
Twitter : @RandR_inc

◆───-- - - - 

ラフアンドレディでの採用はこちら ↓ ↓ ↓

ラフアンドレディでは、みんなのびのびと仕事をしています!エンジニアが長く幸せに活躍できる環境で、仲間と楽しく働いてみませんか?

この記事が参加している募集

つくってみた

この記事が気に入ったらサポートをしてみませんか?