Search code examples
iosswiftgoogle-maps-markersgoogle-maps-sdk-iosinfowindow

How to deselect a GMSMarker after removing custom infowindow in google maps swift


So I have been using Google Maps iOS SDK 4.0.0 and my requirement is like this when I tap on a marker it should add UIViewContoller's view which I easily achieved. Take a look on the following code:

var customeVC:CustomViewController?

func mapView(_ mapView: GMSMapView, didTap marker: GMSMarker) -> Bool {
    
    customeVC = CustomViewController(nibName: "CustomViewController", bundle: nil)
    customeVC?.delegate = self
    self.addChild(customeVC!)
    customeVC?.view.frame = self.view.frame
    self.view.addSubview(customeVC!.view)
    customeVC?.didMove(toParent: self)

    // Remember to return false
    // so marker event is still handled by delegate
    return false
}


func mapView(_ mapView: GMSMapView, markerInfoWindow marker: GMSMarker) -> UIView? {
    
    //Empty the default infowindow
    return UIView()
}


extension MapViewController: CustomViewControllerDelegate {
    // Triggers when I close the full screen view of CustomViewController
    func didCloseWindow() {
        customeVC?.willMove(toParent: nil)
        customeVC?.removeFromParent()
        customeVC?.view.removeFromSuperview()
        customeVC = nil
    }
}

Now the main the problem is, after closing the window/view if I click on the same marker again (2nd time) its doesn't show the view. But if I click once again (3rd time), it shows.

So I'm suspecting after removing the view the marker doesn't get deselected. But when I tap for the 2nd time its gets deselected and tap for the 3rd time get selected again.

I have textfields & buttons inside CustomViewController thats why I didn't add this view inside the delegate function mapView(_ mapView: GMSMapView, markerInfoWindow marker: GMSMarker) -> UIView?. Basically I followed this article which lets you click inside InfoWindow.

I also tried to mapView.selectedMarker = marker inside didTap delegate method and mapView.selectedMarker = nil when removing the view.

How do I deselect the marker so that each time I click on the same marker its should show the view?

Any help will be appreciated. Thanks in advance.


Solution

  • After trying for several days finally I solved it. Basically tapping on marker works every time only if you draw only markers. But if you draw markers inside an overlay or a polygon then tapping on same marker for the 2nd time didn't work because 2nd time the following method of GMSMapViewDelegate gets fired.

    func mapView(_ mapView: GMSMapView, didTap overlay: GMSOverlay)
    

    I didn't mention that, I was drawing markers inside an overlay because I never thought it can cause tapping issue. I found someone else also faced the issue earlier but his question was unanswered. So here is what I needed to update inside that delegate method to make it work and the rest code are the same.

    I'm setting the isTappable polygon property to false when I'm tapping on a certain polygon and then I can play around with the markers which are drawn inside. Also I'm resetting the isTappable property to true of previously selected polygon as soon as user clicks on other polygon.

    class ViewController: GMSMapViewDelegate {
        @IBOutlet weak var mapView:GMSMapView!
        private var selectedPolygon: GMSAptivePolygon?
        
        func mapView(_ mapView: GMSMapView, didTap overlay: GMSOverlay) {
            
            if let polygon = overlay as? GMSPolygon {
                
                // Make sure to restrict markers for a polygon if tapped more than once
                if selectedPolygon != polygon {
                    
                    // Reset polygon to tappable
                    selectedPolygon?.isTappable = true
                    
                    // Fetch all annotations of this polygon if exits
                    fetchMarkers(for: polygon)
                    
                    polygon.isTappable = false
                    selectedPolygon = polygon
                }
            }
        }
    }