Search code examples
uitextfieldmkmapviewswift4.2mkdirection

Directions from one location to another in swift using MapView


MapView Image with 2 TextfieldsHow to draw directions/route from one location to another entered in UITextfield using MapView in swift? The user should enter one location in source textfield and one location in destination textfield. Through the code we should be able to fetch the coordinates of those locations and a direction/route should be created from source to destination when button is pressed. I am new to swift so I am in not situation to work on this yet. I will appreciate some help. Thank you


Solution

  • The basic idea is that you get the coordinates for the “from” and “to” text fields, then calculate the MKDirections for that:

    let geocoder = CLGeocoder()
    
    func getDirections() {
        guard
            let from = fromTextField.text,
            !from.isEmpty,
            let to = toTextField.text,
            !to.isEmpty
        else {
            print("need to and from locations")
            return
        }
    
        geocoder.geocodeAddressString(from) { placemarks, error in
            guard let fromPlacemark = placemarks?.first else {
                print("from", error ?? "Unknown error")
                return
            }
    
            self.geocoder.geocodeAddressString(to) { placemarks, error in
                guard let toPlacemark = placemarks?.first else {
                    print("to", error ?? "Unknown error")
                    return
                }
    
                self.calculateDirections(from: fromPlacemark, to: toPlacemark)
            }
        }
    }
    

    Now, I’m using geocodeAddressString, but you might use MKLocalSearch if you want to constrain the search to the currently visible portion of the map.

    To calculate the directions and add the route to the map:

    func calculateDirections(from fromPlacemark: CLPlacemark, to toPlacemark: CLPlacemark) {
        let request = MKDirections.Request()
        request.source = MKMapItem(placemark: MKPlacemark(placemark: fromPlacemark))
        request.destination = MKMapItem(placemark: MKPlacemark(placemark: toPlacemark))
    
        MKDirections(request: request).calculate { response, error in
            guard let route = response?.routes.first else {
                print("route", error ?? "Unknown error")
                return
            }
    
            self.mapView.addOverlay(route.polyline)
            self.mapView.setVisibleMapRect(route.polyline.boundingMapRect, animated: true)
        }
    }
    

    That obviously assume that you’ve specified the delegate for the map view and have implemented the mapView(_:rendererFor:):

    extension ViewController: MKMapViewDelegate {
        func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
            let renderer = MKPolylineRenderer(overlay: overlay)
            renderer.lineWidth = 5
            renderer.strokeColor = UIColor.blue.withAlphaComponent(0.5)
            return renderer
        }
    }
    

    enter image description here

    There’s obviously a lot more to it (showing error messages in the UI, handling scenarios where the geocode requests or the directions request returned multiple results, presenting a UIActivityIndicatorView while all of this searching/calculating is happening, etc.) but this illustrates a few of the basic moving parts of how to calculate and display directions on a map.