Animate Map to Location is Not Working Google Maps iOS
Asked Answered
W

2

9
import UIKit
import GoogleMaps
import FirebaseDatabase
import GeoFire

class MapViewController: UIViewController, CLLocationManagerDelegate, GMSMapViewDelegate {
    var mapView = GMSMapView()

    var locationManager: CLLocationManager!
    let regionRadius: CLLocationDistance = 1000
    var place = CLLocationCoordinate2D()

    @IBOutlet var myLocationButton: UIButton!
    @IBOutlet var infoWindow: UIView!
    @IBOutlet var postTitle: UILabel!
    @IBOutlet var postImage: UIImageView!

    var showing = false;
    var pins = [String: Pin]()
    var currentMarker = GMSMarker()

    override func viewDidLoad() {
        super.viewDidLoad()

        // sets up the map view (camera, location tracker etc.)
        let camera = GMSCameraPosition.camera(withLatitude: place.latitude, longitude: place.longitude, zoom: 17.0)
        let mapView = GMSMapView.map(withFrame: CGRect.zero, camera: camera)
        mapView.isMyLocationEnabled = true
        mapView.delegate = self
        view = mapView

        self.view.addSubview(myLocationButton)
        self.view.bringSubview(toFront: myLocationButton)

        // Location manager
        locationManager = CLLocationManager()
        locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation
        locationManager.requestAlwaysAuthorization()
        locationManager.delegate = self
        locationManager.startUpdatingLocation()

        // Get nearby records
        let geoFire = GeoFire(firebaseRef: FIRDatabase.database().reference().child("geofire"))
        let query = geoFire?.query(at: CLLocation(latitude: place.latitude, longitude: place.longitude), withRadius: 0.6)

        _ = query?.observe(.keyEntered, with: { (key, location) in
            let marker = GMSMarker()
            let newPin = Pin(title: "post", locationName: "\(key!)", discipline: "", coordinate: (location?.coordinate)!)
            self.pins[newPin.locationName] = newPin
            marker.icon = UIImage(named: "icon_small_shadow")
            marker.position = Pin.coordinate
            marker.title = Pin.title
            marker.snippet = Pin.locationName
            marker.map = mapView
        })

        myLocationTapped(myLocationButton)

    }

    // sets the info in the custom info window
    func mapView(_ mapView: GMSMapView, didTap marker: GMSMarker) -> Bool {

         if(currentMarker == marker && showing) {
           infoWindow.isHidden = true
            showing = false
         } else {
            infoWindow.isHidden = false
            self.view.addSubview(infoWindow)
            self.view.bringSubview(toFront: infoWindow)
            postTitle.text = marker.snippet
            showing = true
        }

        currentMarker = marker

        return true
    }

    @IBAction func myLocationTapped(_ sender: Any) {
       print("tapped")
       let cameraPosition = GMSCameraPosition.camera(withLatitude: place.latitude, longitude: place.longitude, zoom: 15.0)
       mapView.animate(to: cameraPosition)
    }

I have the following code set up, designed to place a button on the google maps map that when tapped, animates the google maps camera to that location. However, my code doesn't work. The "tapped" prints in the console but the camera doesn't budge. I haven't been able to find an answer anywhere for this, so any help would be appreciated.

EDIT: Added full code for the Map View Controller

Whitford answered 13/5, 2017 at 11:28 Comment(5)
Are you explicitly calling button action?Anemology
@Nirav D yes, it's getting called. "Tapped" gets printed every time I tap the button.Whitford
after print(Tapped) and one more print statement like print(place.latitude, place.longitude) and add here the console log of itAnemology
tapped 34.0522 -118.2437Whitford
Problem is in this line view = mapView of viewDidLoad change it with self.mapView = mapView I have also edited my answerAnemology
A
9

Try this way

let cameraPosition = GMSCameraPosition.camera(withLatitude: place.latitude, longitude: place.longitude, zoom: 15.0)
mapView.animate(to: cameraPosition)

Edit: Issue is you aren't having the reference of your map with your mapView object, change your viewDidLoad's line:

view = mapView

TO:

// sets up the map view (camera, location tracker etc.)
let camera = GMSCameraPosition.camera(withLatitude: place.latitude, longitude: place.longitude, zoom: 17.0)
let mapView = GMSMapView.map(withFrame: view.bounds, camera: camera)
mapView.isMyLocationEnabled = true
mapView.delegate = self
self.mapView = mapView
view.addSubview(self.mapView)
Anemology answered 13/5, 2017 at 11:46 Comment(7)
Still not animating. At this point, I'm thinking it must be an error somewhere else in my code because nothing works.Whitford
to the best of my knowledge, there are no asynchronous calls. It's just a MapView code that gets data from firebase for the pins and displays them on the map. I don't think the Firebase loading is the issue.Whitford
I can post the entire map view code if that would be more helpful?Whitford
Place exists -- I checked. I added the full code above.Whitford
I tried that and I get a blank screen. Should I change var mapView = GMSMapView() to var mapView: GMSMapView!?Whitford
@Whitford try to change CGRect.zero to self.view.bounds for frame when you initialized the mapviewAnemology
@Whitford Add mapview as subview in mainView edited answer with itAnemology
B
13

In my case the map wasn't updating because I was not calling the method on the main queue. The following code solved the issue:

DispatchQueue.main.async {
        self.mapView.animate(to: camera)
    }

Anything action related to the user interface should be called in the main queue

By answered 27/2, 2018 at 17:0 Comment(1)
This helped me a lot. Thank you!Triangulation
A
9

Try this way

let cameraPosition = GMSCameraPosition.camera(withLatitude: place.latitude, longitude: place.longitude, zoom: 15.0)
mapView.animate(to: cameraPosition)

Edit: Issue is you aren't having the reference of your map with your mapView object, change your viewDidLoad's line:

view = mapView

TO:

// sets up the map view (camera, location tracker etc.)
let camera = GMSCameraPosition.camera(withLatitude: place.latitude, longitude: place.longitude, zoom: 17.0)
let mapView = GMSMapView.map(withFrame: view.bounds, camera: camera)
mapView.isMyLocationEnabled = true
mapView.delegate = self
self.mapView = mapView
view.addSubview(self.mapView)
Anemology answered 13/5, 2017 at 11:46 Comment(7)
Still not animating. At this point, I'm thinking it must be an error somewhere else in my code because nothing works.Whitford
to the best of my knowledge, there are no asynchronous calls. It's just a MapView code that gets data from firebase for the pins and displays them on the map. I don't think the Firebase loading is the issue.Whitford
I can post the entire map view code if that would be more helpful?Whitford
Place exists -- I checked. I added the full code above.Whitford
I tried that and I get a blank screen. Should I change var mapView = GMSMapView() to var mapView: GMSMapView!?Whitford
@Whitford try to change CGRect.zero to self.view.bounds for frame when you initialized the mapviewAnemology
@Whitford Add mapview as subview in mainView edited answer with itAnemology

© 2022 - 2024 — McMap. All rights reserved.