Search code examples
iosswiftuigesturerecognizeruitapgesturerecognizergmsmapview

Unable to recognize gestures on a subview in a GMSMapView


I currently have a GMSMapView with a UIView subview, but I can't get the subview to recognize tap gestures. I've tried many solutions like setting isUserInteractionEnabled equal to true and overriding the delegate but none have worked so far.

import UIKit
import GoogleMaps
class MapViewController: UIViewController, UIGestureRecognizerDelegate {
    var testView: UIView!
    var mapView: GMSMapView!

    override func viewDidLoad() {
        super.viewDidLoad()
        let camera = GMSCameraPosition.camera(withLatitude: 0, longitude: 0, zoom: 15.0)
        mapView = GMSMapView.map(withFrame: CGRect.zero, camera: camera)
        mapView.isUserInteractionEnabled = true
        self.view = mapView

        let screenSize: CGRect = UIScreen.main.bounds
        let screenWidth = screenSize.width
        let screenHeight = screenSize.height

        testView = UIView()
        testView.backgroundColor = UIColor(white: 0, alpha: 0.5)
        testView.frame.origin = CGPoint(x: 0, y: 0);
        testView.frame.size = CGSize(width: screenWidth, height: screenHeight)
        testView.isUserInteractionEnabled = true

        let gesture = UITapGestureRecognizer(target: self, action: #selector(self.doSomething(_:)))
        gesture.numberOfTapsRequired = 1
        gesture.numberOfTouchesRequired = 1
        gesture.delegate = self
        self.view.addSubview(testView)
        testView.addGestureRecognizer(gesture)
    }

    @objc func doSomething(_ sender: UIGestureRecognizer) {
        print("doSomething")
    } 

    func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
        if (touch.view == gestureRecognizer.view) {
            print("returned true")
            return true
        }
        return false
    }
}

The interesting thing is that when I do tap on testView, it does print out "returned true" from my shouldReceiveTouch function. So I'm not quite sure how the delegate function returns true, yet the selector function isn't firing. I also tried this swipe gestures with another UIView and that did not work either. Any help is appreciated, thank you in advance!


Solution

  • Put the following code:

    mapView.settings.consumesGesturesInView = false
    

    From the Google Maps iOS SDK Reference:

    Controls whether gestures by users are completely consumed by the GMSMapView when gestures are enabled (default YES). This prevents these gestures from being received by parent views.

    When the GMSMapView is contained by a UIScrollView (or other scrollable area), this means that gestures on the map will not be additional consumed as scroll gestures. However, disabling this (set to NO) may be useful to support complex view hierarchies or requirements.