我想让某人可以点击Map
并执行以下操作:
Marker
用户点击的地方- 用户位置可通过原生“蓝点”查看
许多其他应用程序(例如 Uber 或 DoorDash)都具有此功能,但我在网上找不到任何相关信息。文章推荐这种方法,但如果我尝试制作Marker
,它会说这种方法已被弃用。如果我尝试获取tapLocation
不在世界坐标中的位置,那么它就没用了。
Map()
.onTapGesture { tapLocation in
print(tapLocation)
}
.mapControls {
MapUserLocationButton()
}
目前,我有一些令人讨厌的代码来使用MKMapView
附加UITapGestureRecognizer
了的。用户可以点击一个点,它会将点击位置转换为坐标位置,MKMapView
并将其设置为MKPointAnnotation()
。用户位置也被设置为状态变量,因此这会强制不断重新绘制用户位置图钉(令人讨厌)。
import SwiftUI
import MapKit
struct MapInput: UIViewRepresentable {
@Binding var tappedCoordinate: CLLocationCoordinate2D?
@Binding var userLocation: CLLocation?
func makeUIView(context: Context) -> MKMapView {
let mapView = MKMapView()
// Add Tap Gesture Recognizer
let tapGestureRecognizer = UITapGestureRecognizer(
target: context.coordinator,
action: #selector(Coordinator.handleTap(gesture:))
)
mapView.addGestureRecognizer(tapGestureRecognizer)
return mapView
}
func updateUIView(_ uiView: MKMapView, context: Context) {
// Remove existing annotations
uiView.removeAnnotations(uiView.annotations)
// Add new annotation if there's a tapped coordinate
if let coordinate = tappedCoordinate {
let annotation = MKPointAnnotation()
annotation.coordinate = coordinate
annotation.title = "POI"
uiView.addAnnotation(annotation)
}
if let user = userLocation {
let annotation = MKPointAnnotation()
annotation.coordinate = user.coordinate
annotation.title = "USER"
uiView.addAnnotation(annotation)
}
}
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
class Coordinator: NSObject {
var parent: MapInput
init(_ parent: MapInput) {
self.parent = parent
}
@objc func handleTap(gesture: UITapGestureRecognizer) {
let mapView = gesture.view as! MKMapView
let touchPoint = gesture.location(in: mapView)
let coordinate = mapView.convert(touchPoint, toCoordinateFrom: mapView)
parent.tappedCoordinate = coordinate
}
}
}
您可以使用,使用方法来将 转换
CGPoint
为 或从 转换为。CLLocationCoordinate2D
MapReader
convert(_:from:)
但首先,您需要一个结构来存储有关地图上标记的信息,例如
然后,将这些数组存储在 中
@State
,并将其附加到 中onTapGesture
:onTapGesture
请注意,这是.local
默认的坐标空间,因此我们.local
在转换时也会使用它CGPoint
。