Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Tapping an MKMapView in SwiftUI

I have a map in a SwiftUI app. It is working up to a point; but now I want to be able to tap on it and know the latitude and longitude of the tap. Here is the current code:

import SwiftUI
import MapKit

struct MapView: UIViewRepresentable {
    @Binding var centerCoordinate: CLLocationCoordinate2D
    
    func makeUIView(context: Context) -> MKMapView {
        let mapView = MKMapView()
        mapView.delegate = context.coordinator
        
        let gRecognizer = UITapGestureRecognizer(target: context.coordinator,
                                action: #selector(Coordinator.tapHandler(_:)))
        mapView.addGestureRecognizer(gRecognizer)
        return mapView
    }

    func updateUIView(_ view: MKMapView, context: Context) {
        //print(#function)
    }

    func makeCoordinator() -> Coordinator {
        return Coordinator(self)
    }

    class Coordinator: NSObject, MKMapViewDelegate {
        var parent: MapView

        init(_ parent: MapView) {
            self.parent = parent
        }

        let gRecognizer = UITapGestureRecognizer(target: self,
                                                 action: #selector(tapHandler(_:)))
        
        @objc func tapHandler(_ gesture: UITapGestureRecognizer) {
            print(#function)
            .... get useful information here ...
        }
    }
}

In this state I can see when I tap, but I don't get the information I need (.i.e coordinates of the tap). I have tried a few variations of the code after searching the net. At this point it is not yet working. Any relevant tip on the way to go would be very welcome.

like image 409
Michel Avatar asked Sep 05 '25 16:09

Michel


1 Answers

I had a similar situation, and this is what I did. I made Coordinator UIGestureRecognizerDelegate, and ensure gRecognizer delegate is set to it, and add it to the map. Something like:

struct MapView: UIViewRepresentable {
@Binding var centerCoordinate: CLLocationCoordinate2D

let mapView = MKMapView()

func makeUIView(context: Context) -> MKMapView {
    mapView.delegate = context.coordinator
    return mapView
}

func updateUIView(_ view: MKMapView, context: Context) {
    //print(#function)
}

func makeCoordinator() -> Coordinator {
    return Coordinator(self)
}

class Coordinator: NSObject, MKMapViewDelegate, UIGestureRecognizerDelegate {
    var parent: MapView

    var gRecognizer = UITapGestureRecognizer()

    init(_ parent: MapView) {
        self.parent = parent
        super.init()
        self.gRecognizer = UITapGestureRecognizer(target: self, action: #selector(tapHandler)) 
        self.gRecognizer.delegate = self
        self.parent.mapView.addGestureRecognizer(gRecognizer)
    }

    @objc func tapHandler(_ gesture: UITapGestureRecognizer) {
        // position on the screen, CGPoint
        let location = gRecognizer.location(in: self.parent.mapView)
        // position on the map, CLLocationCoordinate2D
        let coordinate = self.parent.mapView.convert(location, toCoordinateFrom: self.parent.mapView)
        
    }
}
}
like image 171
workingdog support Ukraine Avatar answered Sep 07 '25 11:09

workingdog support Ukraine