Googlemaps delegate methods never fired in iOS SwiftUI

46 Views Asked by At

Intergated the Google maps via SPM and maps seems to loaded correctly with few markers on the map, but I wanted to know when the map is fully loaded and when the map is moved etc..

For that we can use the GoogleMaps delegate methods like mapViewDidFinishTileRendering(_ mapView: GMSMapView) & mapViewSnapshotReady(_ mapView: GMSMapView)

But those functions are never been called.

Here is my implementation

import UIKit
import GoogleMaps

class MapViewController: UIViewController {
    var options = GMSMapViewOptions()
    var map = GMSMapView()
    var isAnimating: Bool = false

    override func loadView() {
      super.loadView()
      options.camera = GMSCameraPosition.camera(withLatitude: 18.659553, longitude: 78.105868, zoom: 17.0)
      options.frame = self.view.bounds
      map = GMSMapView(options: options)
      self.view = map
    }
}

import Foundation
import SwiftUI
import GoogleMaps

struct MapViewControllerBridge: UIViewControllerRepresentable {
    
    @Binding var markers: [GMSMarker]
    @Binding var selectedMarker: GMSMarker?
    var onAnimationEnded: () -> ()
    var mapViewWillMove: (Bool) -> ()

    func makeUIViewController(context: Context) -> MapViewController {
        let uiViewController = MapViewController()
        uiViewController.map.delegate = context.coordinator
        return uiViewController
    }

    func updateUIViewController(_ uiViewController: MapViewController, context: Context) {
        markers.forEach { $0.map = uiViewController.map }
        selectedMarker?.map = uiViewController.map
        animateToSelectedMarker(viewController: uiViewController)
    }
    
    func makeCoordinator() -> MapViewCoordinator {
      return MapViewCoordinator(self)
    }
    
    private func animateToSelectedMarker(viewController: MapViewController) {
      guard let selectedMarker = selectedMarker else {
        return
      }

      let map = viewController.map
      if map.selectedMarker != selectedMarker {
        map.selectedMarker = selectedMarker
        DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
          map.animate(toZoom: kGMSMinZoomLevel)
          DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
            map.animate(with: GMSCameraUpdate.setTarget(selectedMarker.position))
            DispatchQueue.main.asyncAfter(deadline: .now() + 0.5, execute: {
              map.animate(toZoom: 12)
              DispatchQueue.main.asyncAfter(deadline: .now() + 0.5, execute: {
                onAnimationEnded()
              })
            })
          }
        }
      }
    }
    
    final class MapViewCoordinator: NSObject, GMSMapViewDelegate {
        var mapViewControllerBridge: MapViewControllerBridge
        
        init(_ mapViewControllerBridge: MapViewControllerBridge) {
            self.mapViewControllerBridge = mapViewControllerBridge
        }
        
        func mapView(_ mapView: GMSMapView, willMove gesture: Bool) {
            self.mapViewControllerBridge.mapViewWillMove(gesture)
        }
        
        func mapViewDidFinishTileRendering(_ mapView: GMSMapView) {
            print("Map Finished Rendering..")
        }
        
        func mapViewSnapshotReady(_ mapView: GMSMapView) {
            print("Map View Snapshot Ready..")
        }
    }
}

Calling the MapViewControllerBridge from the ContentView file

MapViewControllerBridge(markers: $markers, selectedMarker: $selectedMarker, onAnimationEnded: {
                  self.zoomInCenter = true
                }, mapViewWillMove: { (isGesture) in
                  guard isGesture else { return }
                  self.zoomInCenter = false
                })
                .ignoresSafeArea()
1

There are 1 best solutions below

0
vishwa On BEST ANSWER

It seems to be working if I remove the loadView() and use init() instead for the MapViewController class.

class MapViewController: UIViewController {
    var options = GMSMapViewOptions()
    var map = GMSMapView()
    var isAnimating: Bool = false

    init() {
      super.init(nibName: nil, bundle: nil)
      options.camera = GMSCameraPosition.camera(withLatitude: 18.659553, longitude: 78.105868, zoom: 17.0)
      options.frame = self.view.bounds
      map = GMSMapView(options: options)
      self.view = map
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}