teratail header banner
teratail header banner
質問するログイン新規登録

Q&A

解決済

1回答

432閲覧

SwiftUIで、Map()使用して地図を表示中に中心の緯度経度を取得したい。

kuwatsy

総合スコア6

0グッド

0クリップ

投稿2024/06/10 14:07

0

0

実現したいこと

SwiftUIでMapを表示させ、現在地の緯度経度を表示させるところまでは、以下のコードで実現できました。この地図は指でドラッグやピンチ、ひねりで表示エリアや方向を変えられます。

import SwiftUI import MapKit import CoreLocation class LocationManager: NSObject, ObservableObject, CLLocationManagerDelegate { private let locationManager = CLLocationManager() @Published var lastKnownLocation: CLLocationCoordinate2D? override init() { super.init() locationManager.delegate = self locationManager.desiredAccuracy = kCLLocationAccuracyBest locationManager.requestWhenInUseAuthorization() } func requestLocation() { locationManager.requestLocation() } func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { if let location = locations.last { DispatchQueue.main.async { self.lastKnownLocation = location.coordinate } } } func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) { print("Failed to get user location: \(error.localizedDescription)") } } struct ForTeratail: View { @State private var coordinate: CLLocationCoordinate2D = .init(latitude: 0.00, longitude: 0.00) @State private var userCameraPosition: MapCameraPosition = .userLocation(followsHeading: true, fallback: .camera(MapCamera(centerCoordinate: .myHome, distance: 5000, pitch: 60))) @ObservedObject var locationManager = LocationManager() var body: some View { ZStack { VStack { Spacer() VStack(alignment: .leading) { Text("Map Center:") Text("latitude: \(coordinate.latitude)") Text("longitude: \(coordinate.longitude)") } .foregroundColor(.white) .frame(maxWidth: .infinity, alignment: .leading) .padding(8) .background( RoundedRectangle(cornerRadius: 4) .fill(Color.secondary) ) } .padding() .zIndex(100) Map(position: $userCameraPosition) { UserAnnotation() } .mapControls { MapCompass() .mapControlVisibility(.visible) MapPitchToggle() .mapControlVisibility(.visible) MapScaleView() .mapControlVisibility(.visible) MapUserLocationButton() .mapControlVisibility(.visible) } .onAppear { locationManager.requestLocation() } .onReceive(locationManager.$lastKnownLocation) { location in if let location = location { coordinate = location } } } } } #Preview { ForTeratail() }

この状態で、Mapを指でドラッグしたり、ピンチしたりして地図を移動等して指を離したときに、その地図の中心地の緯度経度を取得して表示させたいです。

発生している問題・分からないこと

マップを指で操作して、指を離したときに地図の中心地を得る方法がわかりません。
Map {...} のあと、DragGestureや.onChangeなどで取得できそうなのですが、うまくできません。

該当のソースコード

上記に記入しました

試したこと・調べたこと

  • teratailやGoogle等で検索した
  • ソースコードを自分なりに変更した
  • 知人に聞いた
  • その他
上記の詳細・結果

ChatGPTで解決方法を質問しました。何度か提案が出てきましたが、いずれもエラーが出て、堂々巡りとなったため断念しました。以下のコードでは、
Value of type 'some View' has no member 'onRegionDidChange'
というエラーが出てしまいます。

import SwiftUI import MapKit import CoreLocation class LocationManager: NSObject, ObservableObject, CLLocationManagerDelegate { private let locationManager = CLLocationManager() @Published var lastKnownLocation: CLLocationCoordinate2D? override init() { super.init() locationManager.delegate = self locationManager.desiredAccuracy = kCLLocationAccuracyBest locationManager.requestWhenInUseAuthorization() } func requestLocation() { locationManager.requestLocation() } func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { if let location = locations.last { DispatchQueue.main.async { self.lastKnownLocation = location.coordinate } } } func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) { print("Failed to get user location: \(error.localizedDescription)") } } struct ForTeratail: View { @State private var coordinate: CLLocationCoordinate2D = .init(latitude: 0.00, longitude: 0.00) @State private var userCameraPosition: MapCameraPosition = .userLocation(followsHeading: true, fallback: .camera(MapCamera(centerCoordinate: .myHome, distance: 5000, pitch: 60))) @ObservedObject var locationManager = LocationManager() var body: some View { ZStack { VStack { Spacer() VStack(alignment: .leading) { Text("Map Center:") Text("latitude: \(coordinate.latitude)") Text("longitude: \(coordinate.longitude)") } .foregroundColor(.white) .frame(maxWidth: .infinity, alignment: .leading) .padding(8) .background( RoundedRectangle(cornerRadius: 4) .fill(Color.secondary) ) } .padding() .zIndex(100) Map(position: $userCameraPosition) { UserAnnotation() } .mapControls { MapCompass() .mapControlVisibility(.visible) MapPitchToggle() .mapControlVisibility(.visible) MapScaleView() .mapControlVisibility(.visible) MapUserLocationButton() .mapControlVisibility(.visible) } .onAppear { locationManager.requestLocation() } .onReceive(locationManager.$lastKnownLocation) { location in if let location = location { coordinate = location } } .onRegionDidChange { region in coordinate = region.center } } } } #Preview { ForTeratail() }

補足

特になし

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

onMapCameraChange(frequency:_:) | Apple Developer Documentation

onMapCameraChangeを使用してみたらいかがでしょうか。

swift

1.onMapCameraChange { context in 2 coordinate = context.camera.centerCoordinate 3}

投稿2024/06/11 03:45

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kuwatsy

2024/06/11 12:29

回答ありがとうございます。 試したところ問題が解決しました! たった3行で1週間悩んでいたことが綺麗に解決できまして、感動しております。 ChatGPTも結構よく助けてくれますが、こんなにエレガントには解決してくれません。 ベストアンサーに選ばせていただきました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.30%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問