Google Maps iOS SDK Touch Events - gmsmapview

I'm trying to add an UIGestureRecognizer to one the whole google map view.
I want to get notified if i touch the map ( not the marker ), but i don't know how. what i did is this inside viewDidLoad:
UITapGestureRecognizer* tapRec = [[UITapGestureRecognizer alloc]
initWithTarget:self action:#selector(didTapMap:)];
[mapView_ addGestureRecognizer:tapRec];
and outside viewDidLoad:
- (void)didTapMap:(UITapGestureRecognizer *)recognizer {
NSLog(#"Touched map");
}
but this method don't work and don't print anything on the console window..
please help me and show me how to do it please

I think what you need is already part of the map's delegate
/**
* Called after a tap gesture at a particular coordinate, but only if a marker
* was not tapped. This is called before deselecting any currently selected
* marker (the implicit action for tapping on the map).
*/
- (void)mapView:(GMSMapView *)mapView
didTapAtCoordinate:(CLLocationCoordinate2D)coordinate;
there are other methods in that delegate, take a look a them too.
Use the following function for Swift:
func mapView(_ mapView: GMSMapView, didTapAt coordinate: CLLocationCoordinate2D)

func mapView(_ mapView: GMSMapView, didTapAt coordinate: CLLocationCoordinate2D) {
// In My Case Im adding one overlay view on marker tap.
// infoWindow is a subclass of UIview in my code
infoWindow.removeFromSuperview()
infoWindow = loadNiB()
infoWindow.center = mapView.projection.point(for: marker.position)
infoWindow.center.y = infoWindow.center.y - sizeForOffset(view: infoWindow)
self.view.addSubview(infoWindow)
return false
}

for Swift 3
func mapView(_ mapView: GMSMapView, didTapAt coordinate: CLLocationCoordinate2D) {
NSLog(#"Touched map");
}

- (void) mapView:(GMSMapView *)mapView didTapAtCoordinate (CLLocationCoordinate2D)coordinate{
NSLog(#"User did tap at coordinate %f, %f", coordinate.latitude, coordinate.longitude) ;
NSLog(#"Map view center %f %f and zoom is %f", mapView.camera.target.latitude, mapView.camera.target.longitude, mapView.camera.zoom) ;
}
}

Related

SwiftUI MapKit - Multiple annotations in same map

I've had a look at similar questions but nothing seems to answer this question exactly.
I have a Map view and I want to add pin overlays, as well as a poly line route overlay on top of it. I am very very new at SwiftUI dev (this is my first app), so some help would be appreciated.
At the moment the map only renders the pins, and not the overlay. I'm assuming they need to be put into the same method but cannot figure out how you can return multiple overlays to the mapView.
Here is the Coordinator code:
class Coordinator: NSObject,MKMapViewDelegate{
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
//draw pins
if annotation.isKind(of: MKUserLocation.self){return nil}
else{
let pinAnnotation = MKPinAnnotationView(annotation: annotation, reuseIdentifier: "PIN_VIEW")
pinAnnotation.tintColor = .red
pinAnnotation.animatesDrop = true
pinAnnotation.canShowCallout = true
return pinAnnotation
}
}
private func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKPolylineRenderer? {
//draw route
let render = MKPolylineRenderer(overlay: overlay)
render.strokeColor = .orange
render.lineWidth = 2
return render;
}
}
Here is the output: (no route is drawn). I tried to put the annotations within the same method but couldn't figure out how to return both at the same time (pins are of type MKAnnotationView and the route is of type MKPolylineRenderer...
Help would be really appreciated. Thanks
It should be a separate method, but it shouldn’t be private. Also, the return type should be MKOverlayRenderer.

Get LAT and LONG from tapped overlay in Google Maps

When a user taps an overlay, the following code is triggered:
func mapView(_ mapView: GMSMapView, didTap overlay: GMSOverlay) {
}
I wonder if we can extract the exact LAT and LONG coordinates of the overlay that has been tapped?
Thanks!
To solve this we need the 2 methods together,
So I combined them in a way I hope it will help in this issue:
func mapView(_ mapView: GMSMapView, didTap overlay: GMSOverlay) {
print(overlay)
}
func mapView(_ mapView: GMSMapView, didTapAt coordinate: CLLocationCoordinate2D) {
print(coordinate)
for polyline in polylines {
if GMSGeometryIsLocationOnPath(coordinate, polyline.path!, true) {
self.mapView(mapView, didTap: polyline)
}
}
for polygon in polygons {
if GMSGeometryContainsLocation(coordinate, polygon.path!, true) {
self.mapView(mapView, didTap: polygon)
}
}
}
if the user clicked at coordinate we will deal with this, Then check if this coordinate is contained in any Polyline or Polygon we had defined before, So we fire the event didTap overlay for that overlay.
Make sure to make polylines and polygons isTappable = false
And but in mind this event will be fired for every overlay tapped even though if they are overlaped, You can put return when the if success to take the first overlay only
You can use didTapAt delegate method for the same.
#wajih, for you did the method didTapAt was called when you tap on landmark names or titles? For me it's not getting called.
For my case the landmark title is above the polygon and the didTapAt method is not getting called, but if i set tappable to true then didTap(overlay) is called perfectly.
If you just want to get the exact coordinates wherever you tapped whether on Overlay or not, then there is another delegate of GMSMapViewDelegate which is called whenever we tap on GoogleMaps. In this delegate you can get the exact coordinates where you tapped on map irrespective of tapping on an overlay.
Swift 3.0
func mapView(_ mapView: GMSMapView, didTapAt coordinate: CLLocationCoordinate2D) {
print(coordinate.latitude)
print(coordinate.longitude)
}
If you want to get the coordinate only on tapping marker, then use this delegate method
func mapView(_ mapView: GMSMapView, didTap marker: GMSMarker) -> Bool {
print(marker.position.latitude)
print(marker.position.longitude)
return true
}
Make sure to make your overlay as non-tappable
overlay.isTappable = false
For reference see here

Get Location From Center of Screen Swift MapKit

I'm new on Swift Programming, and I'm trying to build an app that I can get the coordinates of the center of the view with MapKit and Swift 2.
I already can get the current location, but I need if I move on the map, the location set to the new point which will be the center of the screen.
Can you help me with this please?.
Regards,
You can use the regionDidChangeAnimated delegate method and call mapView.centerCoordinate. It will look like the following:
func mapView(mapView: MKMapView, regionDidChangeAnimated animated: Bool) {
var center = mapView.centerCoordinate
}
Also make sure that your Class is extending MKMapViewDelegate and you are calling
self.mapView.delegate = self in your viewDidLoad() function.

Registering a touch event on an MKPointAnnotation

I want to set up a MKPointAnnotation so that when it is tapped I can call another function. Is there anyway to add a gesture recognizer or something like that?
Implement mapView(_ mapView: MKMapView!,didSelectAnnotationView view: MKAnnotationView!) in MKMapViewDelegate

Can we get all the annotation views from MKMapView

Is there any direct method or any suggestion on how to get all the annotations from the MKMapView?
You can access map's annotations using its annotations property. Getting views for all annotations may not be always possible as annotations that are not currently visible on the map may have no views associated with them, but for arbitrary annotation you can try to get a view using -viewForAnnotation: method.
So here how you can iterate through all map's annotations and try to access their views:
for (id<MKAnnotation> annotation in mapView.annotations){
MKAnnotationView* anView = [mapView viewForAnnotation: annotation];
if (anView){
// Process annotation view
...
}
}
In swift 3.
func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView) {
let selectedAnnotation = view.annotation
for annotation in mapView.annotations {
let viewI = mapView.view(for: annotation)
if !(viewI?.annotation is MKUserLocation){
if annotation.isEqual(selectedAnnotation) {
viewI?.image = UIImage(named: "focus.png")
showLifeEventView(anotation: view) //did select a point on Map.
}else{
viewI?.image = UIImage(named: "point.png")
}
}
}
}