Search code examples
swiftxcodeuitapgesturerecognizermkdirection

How do i initiate directions to pin annotations from user location when the user taps the pin?


I have a mkannotationview that generates my annotation points. I have set up user location permissions already so if the authorization is enabled, the user's location shows. I would now like for when a user clicks the pin, to generate the fastest route to the pin from the user's location (only when location authorization is enabled).


Solution

  • assuming you already have a location manager created

    var currentPlacemark: CLPlacemark? 
    
    @IBAction func getDirectionsTapped(_ sender: Any) { //action from storyboard to viewcontroller (command + drag)
        getAddress()
    }
    
    func getAddress(){
        let overlays = mapView.overlays // these lines of code
        mapView.removeOverlays(overlays) // are to clean up your mapview when
        locationManager.stopUpdatingLocation() // a new directions request is made
        
        guard let currentPlacemark = currentPlacemark else {
            return
        }
        
        let directionRequest = MKDirections.Request()
        let destinationPlacemark = MKPlacemark(placemark: currentPlacemark)
        
        directionRequest.source = MKMapItem.forCurrentLocation()
        directionRequest.destination = MKMapItem(placemark: destinationPlacemark)
        
        directionRequest.transportType = ."[your transport type]"
    
        let directions = MKDirections(request: directionRequest)
        directions.calculate { (directionsResponse, error) in
            guard let directionsResponse = directionsResponse else {
                if let error = error { // unused variable
                    print("Error")
            }
                return
        }
            for route in directionsResponse.routes{ //for loop to show all possible routes or let route = directionsResponse.route[0] to get first route only
                self.mapView.addOverlay(route.polyline, level: .aboveRoads) //level is optional
                self.mapView.setVisibleMapRect(route.polyline.boundingMapRect, animated: true)
            }
            
        }
        locationManager.startUpdatingLocation()
    }
    
    func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView) {
        if let location = view.annotation as? [pointannotation name] {
        self.currentPlacemark = MKPlacemark(coordinate: location.coordinate)
        }
    }
    
    func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
        let render = MKPolylineRenderer(overlay: overlay as! MKPolyline)
        render.strokeColor = //choose a color
        return render
    }