Search code examples
iosswiftgoogle-places-apigmsmapview

Update mapview data in separate view controller


Note: you don't have to be familiar with Google Maps SDK or Places SDK to answer this question. Hi I am using a GMSMapView on my main MapViewController and GMSPlacesClient from Places SDK on a child view controller to search and return a list of places. Like this:

Map Search

What I want to do is to send send the mapView's camera target coordinates (the center of the map on the screen) to the child view controller. Basically I just want to pass data to the next view controller.

So far, I have this:

In my child view controller:

let mapViewController = MapViewController()

 func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
         searching = true
       
        
        let target = mapViewController.mapView.camera.target
        
        let northeast = CLLocationCoordinate2D(latitude: target.latitude + 0.1, longitude: target.longitude + 0.1)
      let southwest = CLLocationCoordinate2D(latitude: target.latitude - 0.1, longitude: target.longitude - 0.1)
       
        
      filter.locationBias = GMSPlaceRectangularLocationOption(northeast, southwest)
        
        GMSPlacesClient.shared().findAutocompletePredictions(fromQuery: searchText, filter: filter, sessionToken: nil, callback: { (result, error) in
            if error == nil && result != nil {
                self.matchingItems = result!
               
            }
        })
        mapSearchTableView.reloadData()
       
        
}

and in MapViewController

 @IBOutlet weak var mapViewView: UIView!
    var mapView = GMSMapView()

 override func viewDidLoad() {
        super.viewDidLoad()
       
        locationManager.delegate = self
        
        if CLLocationManager.locationServicesEnabled() {
            
            locationManager.desiredAccuracy = kCLLocationAccuracyBest
            locationManager.startUpdatingLocation()
        }
        else {
            locationManager.requestWhenInUseAuthorization()
        }
        
        
        let camera = GMSCameraPosition.camera(withLatitude: 39.8097343, longitude: -98.5556199, zoom: 3.0)
        mapView = GMSMapView.map(withFrame: self.view.frame, camera: camera)
        mapViewView.addSubview(mapView)
        
        
        mapView.delegate = self
        mapView.isMyLocationEnabled = true

}

    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
     
        let location = locations.last

        let camera = GMSCameraPosition.camera(withLatitude: (location?.coordinate.latitude)!, longitude: (location?.coordinate.longitude)!, zoom: 13.0)

        self.mapView.animate(to: camera)
        
        self.locationManager.stopUpdatingLocation()
        
    }

This doesn't seem to work, as when I print the mapViewController.mapView.camera.target (or the mapView's center coordinates from the MapViewController), in the child view controller it shows up with coordinates of (0,0). I have also tried many other ways, including setting target within the MapViewController itself, and then calling that target from the child view controller, but the child view controller only reads the initialized coordinate for target, and not the updated coordinate like I want it to.

So basically, what I'm asking is if there is a way to continually update the mapView's camera position coordinates (target) in the child view controller. Please let me know if you know!


Solution

  • I solved it! All it took was adding a struct within the original controller- the MapViewController containing the target variable, like this:

     struct setTarget {
            static var target = CLLocationCoordinate2D()
        }
    
    func mapView(_ mapView: GMSMapView, didChange position: GMSCameraPosition) {
            setTarget.target = mapView.camera.target
        }
    
    

    I set the target to the mapView.camera.target every time it updated a location, and then from my child view controller, I called MapViewController.setTarget.target every time that I needed it.