Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to handle touch gestures in SwiftUI in Swift UIKit Map component?

I tried to handle Map UIKit component gestures in SwiftUI application. Xcode shows this warning: "String literal is not a valid Objective-C selector"

// Binding to UIKit component

import SwiftUI
import MapKit

struct MapView: UIViewRepresentable {

    class Coordinator: NSObject, MKMapViewDelegate {
        @Binding var selectedPin: MapPin?

        init(selectedPin: Binding<MapPin?>) {
            self._selectedPin = selectedPin
        }

        func mapView(_ mapView: MKMapView,
                     didSelect view: MKAnnotationView) {
            guard let pin = view.annotation as? MapPin else {
                return
            }
            pin.action?()
            selectedPin = pin
        }

        func mapView(_ mapView: MKMapView, didDeselect view: MKAnnotationView) {
            guard (view.annotation as? MapPin) != nil else {
                return
            }
            selectedPin = nil
        }
       }

    @Binding var pins: [MapPin]
    @Binding var selectedPin: MapPin?

    func makeCoordinator() -> Coordinator {
      return Coordinator(selectedPin: $selectedPin)
    }

    func makeUIView(context: Context) -> MKMapView {
        let view = MKMapView(frame: .zero)
        let gRecognizer = UITapGestureRecognizer(target: self, action: #selector(triggerTouchAction(gestureRecognizer:)))
          view.addGestureRecognizer(gRecognizer)
          view.delegate = context.coordinator
          return view
    }

    func updateUIView(_ uiView: MKMapView, context: Context) {
        uiView.removeAnnotations(uiView.annotations)
        uiView.addAnnotations(pins)
        if let selectedPin = selectedPin {
            uiView.selectAnnotation(selectedPin, animated: false)
        }
    }

    @objc func triggerTouchAction(gestureReconizer: UITapGestureRecognizer) {
          //Add alert to show it works
        print("Hello, tap!")
    }
}

I expect messages in my Xcode console, but no touch events produced.

Environment: Xcode 11 beta 6 macOS Mojave 10.14.6

like image 772
Serge Almazov Avatar asked Aug 20 '19 16:08

Serge Almazov


1 Answers

@objc can't be applied to functions inside structs. Move the function inside the Coordinator and then change the UIGestureRecognizer declaration this way:

let gRecognizer = UITapGestureRecognizer(target: context.coordinator, action: #selector(Coordinator.triggerTouchAction(gestureReconizer:)))
like image 171
Lorenzo Santini Avatar answered Oct 09 '22 04:10

Lorenzo Santini