Search code examples
iosswiftgoogle-mapsgoogle-maps-sdk-ios

How to set initial map location in Swift?


I am trying to set initial location on map to the coordinate I get from user profile stored in database say userLocation. I call GMSCameraPosition in viewDidLoad but have noticed that simulator detects current location and centers the map on it rather than location I am trying to set. I can see map positioned on userLocation briefly but immediately moves to current location.

I am even calling stopUpdatingLocation method but no success.

Does stopUpdatingLocation call location update once before stopping? That's what it appeared to me when I traced using breakpoints!

And does GMSCameraPosition also change underlying coordinates or just focus in the coordinate provided?

Below is the code.

override func viewDidLoad() {
    super.viewDidLoad()

    locationManager.delegate = self
    locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters
    locationManager.distanceFilter = 50
    locationManager.requestWhenInUseAuthorization()

    mapView.delegate = self

    if userLocation != nil {

        mapView.myLocationEnabled = false
        locationManager.stopUpdatingLocation()

        mapView.camera = GMSCameraPosition(target: selectedCoordinate!.coordinate, zoom: 15, bearing: 0, viewingAngle: 0)
    } 

}

extension MapViewController: CLLocationManagerDelegate {

    func locationManager(manager: CLLocationManager, didChangeAuthorizationStatus status: CLAuthorizationStatus) {
        if status == .AuthorizedWhenInUse {

            locationManager.startUpdatingLocation()

            mapView.myLocationEnabled = true
            mapView.settings.myLocationButton = true
        }
    }

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

            mapView.camera = GMSCameraPosition(target: location.coordinate, zoom: 15, bearing: 0, viewingAngle: 0)

            locationManager.stopUpdatingLocation()
        }

    }

}

extension MapViewController: GMSMapViewDelegate {

    func mapView(mapView: GMSMapView, idleAtCameraPosition position: GMSCameraPosition) {

        reverseGeocodeCoordinate(position.target)

    }
}

Thanks


Solution

  • Add :-

    locationManager. stopMonitoringSignificantLocationChanges() after locationManager.stopUpdatingLocation()

    Also Mind that CLLocationManagerDelegate is an asynchronously run class protocol which means once you execute line mapView.delegate = self, you have initialised your delegate to self which will send a call to fetch usersCurrentLocation geoCoordinates which means it will check if it's protocols Delegate methods are conformed in that particular class , Because if they are then it will call those methods irrespective of wether or not you have called stopUpdatingLocation().

    So solution :-

    func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
    
       if userLocation != nil {
    
    
    
        locationManager.stopUpdatingLocation()
    
    
        mapView.camera = GMSCameraPosition(target: selectedCoordinate!.coordinate, zoom: 15, bearing: 0, viewingAngle: 0)
    } else if let location = locations.first {
    
             mapView.camera = GMSCameraPosition(target: location.coordinate, zoom: 15, bearing: 0, viewingAngle: 0)
    
             locationManager.stopUpdatingLocation()
       }
    
    }