How to detect camera position for google map in swift - ios

I get to know after searching that idleAtCameraPosition and didChangeCameraPosition this methods are called when the map moves .
How can i write this method for swift? I have set delegate to CLLocationManagerDelegate and GMSMapViewDelegate but still this methods are not called. I have written method as below:
func mapView(mapView: GMSMapView!, didChangeCameraPosition position: GMSCameraPosition!) {
print(position)
}
func mapView(mapView:GMSMapView!,idleAtCameraPosition position:GMSCameraPosition!)
{
print(position)
}
But my method is not getting called.
Also I want to customise info window just like done here : Custom Info Window for Google Maps . But can't find the methods how to do same in swift. I am new to swift s o not getting this.

Maybe too late, but you must extend the class with GMSMapViewDelegate. For example:
class NearMeViewController: CLLocationManagerDelegate, GMSMapViewDelegate
Then, how Ztan says, you have to delegate your map with:
self.mapView.delegate = self
With this, the method didChangeCameraPosition will respond every time that that camera's position is changed.
Hope it helps.

You need to import the GMSMapViewDelegate at the top of your class
put self.mapView.delegate = self in your viewDidLoad()
and then you can use this method
func mapView(mapView: GMSMapView, idleAtCameraPosition position: GMSCameraPosition) {
// You can use the position.target for get the current camera position
}

Related

How to show recenter button only when map moves using Swift?

I'm using the default Google Map recenter button which is shown by default. How do I ensure that the recenter button is not shown by default and it's only shown when someone moves the map using Swift?
func SetupMap() {
googleMapView.settings.myLocationButton = true
}
That's pretty easy. You know how to toggle the visibility of the myLocationButton, so what's left is to think harder.
If you take time to review the GoogleMap's GMSMapViewDelegate, you will see that there are couple of methods/functions that will allow you to further your idea.
So set your mapView's delegate to your class (controller), and conform to that GMSMapViewDelegate protocol, and then implement those methods.
willMove
didChange position
These are all you need.
The willMove gets invoked when you start dragging the mapView. On the other hand, the didChange position gets called when the camera did change.
If you do these things, you'll get even nearer towards your goal. However, you might need some debounce feature in your code, because you only want to hide the location button just once, just after the user stops dragging the camera.
var debounce_timer: Timer?
extension MapsViewController: GMSMapViewDelegate {
func mapView(_ mapView: GMSMapView, willMove gesture: Bool) {
print("GMS: will move")
mapView.settings.myLocationButton = true
}
func mapView(_ mapView: GMSMapView, didChange position: GMSCameraPosition) {
print("GMS: didChane camera position")
debounce_timer?.invalidate()
debounce_timer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: false) { _ in
mapView.settings.myLocationButton = false
}
}
}
Voila!
Demo:

How to detect when tap on google map iOS Swift?

I want to check and detect when tap on map marker or anything. Do any delegates exist for this case with google maps in iOS Swift 4?
Thanks.
func mapView(_ mapView: GMSMapView, didTapAt coordinate: CLLocationCoordinate2D) {
//Write your code here...
}
if the delegate function is not called then set the mapview delegate in viewDidAppear() method or in LocationManager didUpdateLocations() method.

Get lat/long from the google mapview

I need to get the lat/long of the location where user taps on the google map view. Is there a necessity to open GooglePlacePickerViewController for this? I need to achieve this in the GMSMapView which is used to show user current location.
It is simple use Delegate method
First set delegate
self.mapView.delegate = self
Then just
extension YourViewController:GMSMapViewDelegate {
func mapView(_ mapView: GMSMapView, didTapAt coordinate: CLLocationCoordinate2D) {
// USER TAP ON coordinate
}
}
Suggestion : Just go through this tutorial https://medium.freecodecamp.org/how-you-can-use-the-google-maps-sdk-with-ios-using-swift-4-a9bba26d9c4d will not take more than 20 min that my promise will conver all the basic stuff. :)
If you need points of view based system. for example if you want what is exact point where user tap according to view X, Y
Then
you can do it like this
let points:CGPoint = mapView.projection.point(for:coordinates)
Bingo !!
assign delegate like this.
mapView.delegate = self
And use GMSMapViewDelegate to use below method
func mapView(_ mapView: GMSMapView, didTapAt coordinate: CLLocationCoordinate2D) {
print("You tapped at Location \(coordinate.latitude), \(coordinate.longitude)")
}

MKMapView and user location timing

I am working with a MKMapView that is placed on the third VC (MapViewController: UIViewController) in a tabbed application controller (AppTabController: UITabViewController). If I understand UITabViewController correctly, the MapViewController will not be instantiated until the user navigates to it.
The MKMapView is linked to the MapViewController via the outlet
#IBOutlet weak var mapView: MKMapView!
MapViewController conforms to the MKMapViewDelegate protocol through an extension to MapViewController and I’ve set the MKMapView delegate in the viewDidLoad method of MapViewController.
extension MapViewController: MKMapViewDelegate {
// delegate methods
}
override func viewDidLoad() {
super.viewDidLoad()
mapView.delegate = self
}
In viewDidLoad of MapViewController I call showMyLocation() to centre the map on the user’s location in a 1 km. by 1 km. region and show their annotation.
The same method is linked to a “User” button on MapViewController’s nav bar which allows the user to return to their location if they want to.
#IBAction func showMyLocation() {
let region = MKCoordinateRegionMakeWithDistance(mapView.userLocation.coordinate, 1000, 1000)
mapView.setRegion(mapView.regionThatFits(region), animated: true)
}
I am not using a CLLocationManager to determine the user’s location. Because MKMapView is able to return the user’s location to the app.
Answers I've found so far point towards a CLLocationManager approach.
I am a little unsure about what appears to be a timing dependency in obtaining the user’s coordinates from MKMapView.
If I start the app and navigate immediately to the MapViewController tab the coordinates returned by mapView.userLocation.coordinate are 0,0
However if I start the app and wait for a minute or so before going to the MapViewController tab the coordinates are the expected ones for my location.
Finally, if I start the app and navigate immediately to the MapViewController the coordinates are 0,0 as above but if I immediately tap the “User” button the coordinates immediately update to the expected ones without the delay.
My solution so far is to implement the didUpdateUserLocation delegate method to tell me when MKMapView has obtained a valid location for the user.
func mapView(mapView: MKMapView, didUpdateUserLocation userLocation: MKUserLocation) {
if self.rideLocations.isEmpty {
self.showUserLocation()
}
}
My question is have I implemented the necessary pattern to deal with MKMapView user location behaviour timing?
My objective is to have the user’s location properly displayed on the MKMapView regardless of when they navigate to the tab that has the map on it but to avoid overuse of the device location services.
Thanks for all the answers so far - they’ve been a massive help in my Swift / IOS journey!
I know this is an old thread, but I thought I would add my two cents in case it helps someone else. To solve this problem you can implement the mapView delegate method mapView(_:viewFor:) which gets called every time an annotation is added to the map. This includes the user location. Just add the code at the top of the method. It's only called once when the MKUserLocation annotation is added to the mapView. In viewDidLoad disable the button.
`func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView?{
if annotation is MKUserLocation {
//return nil so map view draws "blue dot" for standard user location
showMyLocation()
enable your button here.
return nil
}
//other code here.`

Auto reload map in Swift

I am building an iOS app in swift that use the google maps.
The app show the POI near the user, and when I move the map I refresh the POI using a refresh button
#IBAction func refreshPlaces(sender: AnyObject) {
fetchNearbyPlaces(mapView.camera.target)
}
Can I can refresh the POI when I move the map?
Make sure that you declare that your view controller conforms to the GMSMapViewDelegate and that you set self.mapView.delegate = self in that view controller (usually in viewDidLoad).
Then add the rolling method in your view controller:
func mapView(mapView: GMSMapView!, didChangeCameraPosition position: GMSCameraPosition!) {
fetchNearbyPlaces(position.target)
}

Resources