Search code examples
iosswiftgoogle-mapsmap-directions

Navigate from current location to marker


Hello i have multiple markers like this:

var Groningen = GMSMarker()
        marker.position = CLLocationCoordinate2DMake(...., .....)
        marker.title = "...."
        marker.icon = UIImage(named: "...")
        marker.snippet = "....."
        marker.map = mapView

var marker1= GMSMarker()
        marker1.position = CLLocationCoordinate2DMake(...., .....)
        marker1.title = "...."
        marker1.icon = UIImage(named: "...")
        marker1.snippet = "....."
        marker1.map = mapView

In want to add a button in the InfoWindow or in a label below the map that will set directions from the current location to de selected marker.

When the user click on the button its get question like this:

func mapView(mapView: GMSMapView!, didTapInfoWindowOfMarker marker: GMSMarker!) {

        let actionSheetController: UIAlertController = UIAlertController(title: "Navigeer", message: "Kies een optie!", preferredStyle: .ActionSheet)

        //Create and add the Cancel action
        let cancelAction: UIAlertAction = UIAlertAction(title: "Cancel", style: .Cancel) { action -> Void in
            //Do some stuff
        }
        actionSheetController.addAction(cancelAction)
        //Create and add first option action
        let GoGoogleMaps: UIAlertAction = UIAlertAction(title: "Google Maps", style: .Default) { action -> Void in
            if (UIApplication.sharedApplication().canOpenURL(NSURL(string:"comgooglemaps://")!)) {
                UIApplication.sharedApplication().openURL(NSURL(string:
                    "comgooglemaps://?center=40.765819,-73.975866&zoom=14&views=traffic")!)
            } else {
                UIApplication.sharedApplication().openURL(NSURL(string:
                    "https://maps.google.com/?daddr=Amsterdam")!);

            }

            //Do some other stuff
        }
        actionSheetController.addAction(GoGoogleMaps)
        //Create and add a second option action
        let GoAppleMaps: UIAlertAction = UIAlertAction(title: "Apple Maps", style: .Default) { action -> Void in

            if (UIApplication.sharedApplication().canOpenURL(NSURL(string:"http://maps.apple.com")!)) {
                UIApplication.sharedApplication().openURL(NSURL(string:
                    "http://maps.apple.com/?daddr=Amsterdam")!)
            } else {
                NSLog("Can't use Apple Maps");
            }

            //Do some other stuff
        }
        actionSheetController.addAction(GoAppleMaps)

        //We need to provide a popover sourceView when using it on iPad
       actionSheetController.popoverPresentationController?.sourceView = sender as! UIView;

        //Present the AlertController
        self.presentViewController(actionSheetController, animated: true, completion: nil)
    }

Is this possible in a way.


Solution

  • Based on this Stackoverflow answer, there is no easy way to add a touch event on a button in custom info window.

    (You could instead implement GMSMapViewDelegate's -didTapInfoWindowOfMarker: delegate method to check if the infowindow was tapped. (the drawback is that the entire infowindow becomes one button))

    But if you want to add an UILabel in your MapView, you need to set the consumesGesturesInView to be false. So the UILabel can receive touch events.

    Sample Code of adding an UILabel with touch event:

     override func viewDidLayoutSubviews() {
            super.viewDidLayoutSubviews()
    
            let label = UILabel(frame: CGRectMake(view.frame.size.width - 100, view.frame.size.height - 40, 80, 30))
            label.backgroundColor = UIColor.whiteColor()
            label.text = "direction"
            label.textAlignment = .Center
            label.layer.cornerRadius = 10
            label.clipsToBounds = true
            label.userInteractionEnabled = true
    
            let tap = UITapGestureRecognizer(target: self, action: "directionTapped")
            label.addGestureRecognizer(tap)
    
            mapView!.settings.consumesGesturesInView = false
            mapView!.addSubview(label)
            mapView!.bringSubviewToFront(label)
    
        }
    

    Sample Code of showing Maps direction options:

     func directionTapped() {
            let openMapsActionSheet = UIAlertController(title: "Open in Maps", message: "Choose a maps application", preferredStyle: .ActionSheet)
            openMapsActionSheet.addAction(UIAlertAction(title: "Apple Maps", style: .Default, handler: { (action: UIAlertAction!) -> Void in
                let placemark = MKPlacemark(coordinate: CLLocationCoordinate2DMake(self.mapView!.selectedMarker.position.latitude, self.mapView!.selectedMarker.position.longitude), addressDictionary: nil)
                let item = MKMapItem(placemark: placemark)
                let options = [MKLaunchOptionsDirectionsModeKey:
                    MKLaunchOptionsDirectionsModeDriving,
                    MKLaunchOptionsShowsTrafficKey: true]
                item.openInMapsWithLaunchOptions(options as [NSObject : AnyObject])
            }))
            openMapsActionSheet.addAction(UIAlertAction(title: "Google Maps", style: .Default, handler: { (action: UIAlertAction!) -> Void in
                if (UIApplication.sharedApplication().canOpenURL(NSURL(string:"comgooglemaps://")!)) {
                    UIApplication.sharedApplication().openURL(NSURL(string:
                        "comgooglemaps://?saddr=\(self.mapView!.selectedMarker.position.latitude),\(self.mapView!.selectedMarker.position.longitude)&daddr=\(self.mapView!.selectedMarker.position.latitude),\(self.mapView!.selectedMarker.position.longitude)")!)
                } else {
                    UIApplication.sharedApplication().openURL(NSURL(string:
                        "http://maps.google.com/maps?saddr=\(self.mapView!.selectedMarker.position.latitude),\(self.mapView!.selectedMarker.position.longitude)&daddr=\(self.mapView!.selectedMarker.position.latitude),\(self.mapView!.selectedMarker.position.longitude)")!)
                }
            }))
            openMapsActionSheet.addAction(UIAlertAction(title: "Cancel", style: .Cancel, handler: nil))
            presentViewController(openMapsActionSheet, animated: true, completion: nil)
        }