Quero fazer com que alguém possa tocar em a Map
e fazer o seguinte:
- A
Marker
é feita onde o usuário tocou - A localização do usuário é visível com o "ponto azul" nativo
Muitos outros aplicativos como Uber ou DoorDash fazem isso ser possível, mas não consigo encontrar nada relevante sobre isso online. Os artigos recomendam esse método, mas se eu tentar fazer um Marker
, ele diz que isso foi descontinuado. Se eu tentar obter tapLocation
a localização não está em coordenadas mundiais, então não é útil.
Map()
.onTapGesture { tapLocation in
print(tapLocation)
}
.mapControls {
MapUserLocationButton()
}
Atualmente, tenho um código desagradável para usar um MKMapView
com um UITapGestureRecognizer
anexado a ele. O usuário pode tocar em um ponto e ele obtém o local do toque convertido para o local de coordenadas do MKMapView
e definido como um MKPointAnnotation()
. O local do Usuário também é definido como uma variável de estado, então isso força redesenhos do pino de Localização do USUÁRIO constantemente (desagradável).
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
}
}
}
Você pode converter um
CGPoint
para/de umCLLocationCoordinate2D
usando umMapReader
, usando oconvert(_:from:)
método .Mas primeiro, você precisa de uma estrutura para armazenar informações sobre os marcadores no mapa, por exemplo
Em seguida, armazene uma matriz destes em um
@State
e anexe a ele emonTapGesture
:Observe que o espaço de coordenadas
onTapGesture
é.local
o padrão, por isso o usamos.local
ao converterCGPoint
também.