Search code examples
iosswiftxcodeaddsubviewgmsmapview

Is there a way to have InfoWindow open on App load in Google Maps API?


Currently my app opens a custom infowindow when the MapView delegate calls the didTap protocol. This then calls a function which initializes the needed aspects of the infowindow shown below ...

var tappedOverlay : GMSOverlay?
var customInfoWindow : CustomInfoWindow?
var mapView: GMSMapView!

override func viewDidLoad(){
        super.viewDidLoad()

        self.customInfoWindow = CustomInfoWindow().loadView()

        let camera = GMSCameraPosition.camera(withLatitude: 37, longitude: -77, zoom: 16.0)
        mapView = GMSMapView.map(withFrame: CGRect.zero, camera: camera)
        mapView.delegate = self
        self.view = mapView

        //this is where i attempt to force a infoWindow to open
        tappedOverlay = overlay
        initInfoWindow(overlay: overlay)
}

fun initInfoWindow(overlay: GMSOverlay){

        mapView.animate(toLocation: position!)
        let point = mapView.projection.point(for: position!)
        let newPoint = mapView.projection.coordinate(for: point)
        let camera = GMSCameraUpdate.setTarget(newPoint)
        mapView.animate(with: camera)

        let background = UIColor.infoWindowBackground
        customInfoWindow?.layer.backgroundColor = background.cgColor
        customInfoWindow?.layer.cornerRadius = 8
        customInfoWindow?.center = mapView.projection.point(for: position!)
        customInfoWindow?.center.y -= 100
        customInfoWindow?.CustomWindowLabel.text =  overlay.title
        customInfoWindow?.CustomWindowSubLabel.lineBreakMode = .byWordWrapping
        customInfoWindow?.CustomWindowSubLabel.numberOfLines = 0

        mapView.addSubview(customInfoWindow!)
}

func mapView(_ mapView: GMSMapView, didTap Overlay: GMSOverlay){
        initInfoWindow(overlay: overlay)
}

Now I would like to have the app automatically open a certain infowindow as soon as it loads.

When I try to manually display the infoWindow on load by calling the function in viewDidLoad(), I have to comment out the mapView.animate(with: camera) line otherwise the map tiles will never load. Someone pointed out to me that the mapView methods have some 'background' information about the overlay when they are called, so I added the tappedOverlay = overlay line, this gets close in that part of the infoWindow is displayed when the app is loaded. However, this and all other 'regular' infoWindows appear without a background and not centered on the point and cannot be interacted with.

The infoWindow's are a subclass of UIView loaded from a XIB file.

The above code is what I thought would be relevant extracted from a larger code base. Let me know if anything needs to be added!

Any help is appreciated!


Solution

  • Maybe this answer will help someone else. The issue was in the mapView.projection functions, they were returning essentially default values. I'm not entirely sure, but it seems when you click on a marker the mapView changes part of the frame = ( 0 0;) variable in the background, so this lead me to change the mapView initialization.

    So instead of ...

    let camera = GMSCameraPosition.camera(withLatitude: 37, longitude: -77, zoom: 16.0)
    mapView = GMSMapView.map(withFrame: CGRect.zero, camera: camera) 
    

    We need ...

    let camera = GMSCameraPosition.camera(withLatitude: LAT_OF_YOUR_INFOWINDOW, 
                                             longitude: LONG_OF_YOUR_INFOWINDOW,
                                                  zoom: 16.0)
    mapView = GMSMapView.map(withFrame: self.view.bounds, camera: camera)