在 SwiftUI 的 MapView 中检测长按
Detect longpress in MapView for SwiftUI
我在 SwiftUi 中有一个 MapView,当用户长按地图上的某个位置时,我试图向其添加图钉注释。我看到这可以在 swift 中轻松完成,但是我使用的是 SwiftUI。我不知道如何添加长按检测器。最好有代码示例。
我的地图视图
struct MapView: UIViewRepresentable {
@Binding
var annotations: [PinAnnotation]
let addAnnotationListener: (PinAnnotation) -> Void
func makeUIView(context: Context) -> MKMapView {
let mapView = MKMapView()
mapView.delegate = context.coordinator
return mapView
}
func updateUIView(_ view: MKMapView, context: Context) {
view.delegate = context.coordinator
view.addAnnotations(annotations)
if annotations.count == 1 {
let coords = annotations.first!.coordinate
let region = MKCoordinateRegion(center: coords, span: MKCoordinateSpan(latitudeDelta: 0.1, longitudeDelta: 0.1))
view.setRegion(region, animated: true)
}
}
func makeCoordinator() -> MapViewCoordinator {
MapViewCoordinator(self)
}
}
地图视图协调器
class MapViewCoordinator: NSObject, MKMapViewDelegate {
var mapViewController: MapView
init(_ control: MapView) {
self.mapViewController = control
}
func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) {
let annotation = view.annotation
guard let placemark = annotation as? MKPointAnnotation else { return }
}
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView?{
//Custom View for Annotation
let identifier = "Placemark"
if let annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: identifier) {
annotationView.annotation = annotation
return annotationView
} else {
let annotationView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: identifier)
annotationView.isEnabled = true
annotationView.canShowCallout = true
let button = UIButton(type: .infoDark)
annotationView.rightCalloutAccessoryView = button
return annotationView
}
}
}
将图钉添加到 MapView 的方法
func addPinBasedOnGesture(gestureRecognizer:UIGestureRecognizer){
var touchPoint = gestureRecognizer.locationInView(mapView)
var newCoordinates = self.convertPoint(touchPoint, toCoordinateFromView: mapView)
let annotation = MKPointAnnotation()
annotation.coordinate = newCoordinates
mapView.addAnnotation(annotation)
}
在下面找到所提供代码的修改部分以获得所需的行为:
struct SUMapView: UIViewRepresentable {
// ... other your code here
func makeUIView(context: Context) -> MKMapView {
let mapView = MKMapView()
mapView.delegate = context.coordinator
let longPressed = UILongPressGestureRecognizer(target:
context.coordinator, action: #selector(addPin(gesture:)))
mapView.addGestureRecognizer(longPressed)
return mapView
}
// ... other your code here
}
class MapViewCoordinator: NSObject, MKMapViewDelegate {
// ... other your code here
@objc func addPin(gesture: UILongPressGestureRecognizer) {
// do whatever needed here
}
// ... other your code here
}
下面的解决方案在用户长按地图的位置添加了一个图钉。
在MapViewCoordinator
中添加以下方法
@objc func addPinBasedOnGesture(_ gestureRecognizer:UIGestureRecognizer) {
let touchPoint = gestureRecognizer.location(in: gestureRecognizer.view)
let newCoordinates = (gestureRecognizer.view as? MKMapView)?.convert(touchPoint, toCoordinateFrom: gestureRecognizer.view)
let annotation = PinAnnotation()
guard let _newCoordinates = newCoordinates else { return }
annotation.coordinate = _newCoordinates
mapViewController.annotations.append(annotation)
}
和长按手势代码在func makeUIView(context: Context) -> MKMapView {}
func makeUIView(context: Context) -> MKMapView {
let mapView = MKMapView()
mapView.delegate = context.coordinator
let longPressed = UILongPressGestureRecognizer(target: context.coordinator,
action: #selector(context.coordinator.addPinBasedOnGesture(_:)))
mapView.addGestureRecognizer(longPressed)
return mapView
}
我在 SwiftUi 中有一个 MapView,当用户长按地图上的某个位置时,我试图向其添加图钉注释。我看到这可以在 swift 中轻松完成,但是我使用的是 SwiftUI。我不知道如何添加长按检测器。最好有代码示例。
我的地图视图
struct MapView: UIViewRepresentable {
@Binding
var annotations: [PinAnnotation]
let addAnnotationListener: (PinAnnotation) -> Void
func makeUIView(context: Context) -> MKMapView {
let mapView = MKMapView()
mapView.delegate = context.coordinator
return mapView
}
func updateUIView(_ view: MKMapView, context: Context) {
view.delegate = context.coordinator
view.addAnnotations(annotations)
if annotations.count == 1 {
let coords = annotations.first!.coordinate
let region = MKCoordinateRegion(center: coords, span: MKCoordinateSpan(latitudeDelta: 0.1, longitudeDelta: 0.1))
view.setRegion(region, animated: true)
}
}
func makeCoordinator() -> MapViewCoordinator {
MapViewCoordinator(self)
}
}
地图视图协调器
class MapViewCoordinator: NSObject, MKMapViewDelegate {
var mapViewController: MapView
init(_ control: MapView) {
self.mapViewController = control
}
func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) {
let annotation = view.annotation
guard let placemark = annotation as? MKPointAnnotation else { return }
}
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView?{
//Custom View for Annotation
let identifier = "Placemark"
if let annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: identifier) {
annotationView.annotation = annotation
return annotationView
} else {
let annotationView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: identifier)
annotationView.isEnabled = true
annotationView.canShowCallout = true
let button = UIButton(type: .infoDark)
annotationView.rightCalloutAccessoryView = button
return annotationView
}
}
}
将图钉添加到 MapView 的方法
func addPinBasedOnGesture(gestureRecognizer:UIGestureRecognizer){
var touchPoint = gestureRecognizer.locationInView(mapView)
var newCoordinates = self.convertPoint(touchPoint, toCoordinateFromView: mapView)
let annotation = MKPointAnnotation()
annotation.coordinate = newCoordinates
mapView.addAnnotation(annotation)
}
在下面找到所提供代码的修改部分以获得所需的行为:
struct SUMapView: UIViewRepresentable {
// ... other your code here
func makeUIView(context: Context) -> MKMapView {
let mapView = MKMapView()
mapView.delegate = context.coordinator
let longPressed = UILongPressGestureRecognizer(target:
context.coordinator, action: #selector(addPin(gesture:)))
mapView.addGestureRecognizer(longPressed)
return mapView
}
// ... other your code here
}
class MapViewCoordinator: NSObject, MKMapViewDelegate {
// ... other your code here
@objc func addPin(gesture: UILongPressGestureRecognizer) {
// do whatever needed here
}
// ... other your code here
}
下面的解决方案在用户长按地图的位置添加了一个图钉。
在MapViewCoordinator
@objc func addPinBasedOnGesture(_ gestureRecognizer:UIGestureRecognizer) {
let touchPoint = gestureRecognizer.location(in: gestureRecognizer.view)
let newCoordinates = (gestureRecognizer.view as? MKMapView)?.convert(touchPoint, toCoordinateFrom: gestureRecognizer.view)
let annotation = PinAnnotation()
guard let _newCoordinates = newCoordinates else { return }
annotation.coordinate = _newCoordinates
mapViewController.annotations.append(annotation)
}
和长按手势代码在func makeUIView(context: Context) -> MKMapView {}
func makeUIView(context: Context) -> MKMapView {
let mapView = MKMapView()
mapView.delegate = context.coordinator
let longPressed = UILongPressGestureRecognizer(target: context.coordinator,
action: #selector(context.coordinator.addPinBasedOnGesture(_:)))
mapView.addGestureRecognizer(longPressed)
return mapView
}