As far as?I understood your question I am proposing this solution in which i have drawn a polly live between two locations, Once user tap on that car annotation car annotation will run on path same like uber.
You can animate your custom annotation by making custom method??moveCar(_ destinationCoordinate : CLLocationCoordinate2D) and??passing latest value of coordinate which you are getting from server.
ViewController
import UIKit
import MapKit
class ViewController: UIViewController {
//--------------------------------------------------
//MARK
//MARK: - IBOutlets
//--------------------------------------------------
@IBOutlet weak var mapView: MKMapView!
var pointAnnotation : CarCustomAnnotation!
var pinAnnotationView : MKAnnotationView!
let sourceCoordinate : CLLocationCoordinate2D? = CLLocationCoordinate2D(latitude: 23.034373 , longitude: 72.564163)
let destinationCoordinate : CLLocationCoordinate2D? = CLLocationCoordinate2D(latitude: 23.035141,longitude:72.564451)
let reuseIdentifier = "pin"
//--------------------------------------------------
//MARK:
//MARK: - Custom Methods
//--------------------------------------------------
func degreesToRadians(degrees: Double) -> Double { return degrees * .pi / 180.0 }
func radiansToDegrees(radians: Double) -> Double { return radians * 180.0 / .pi }
func getHeadingForDirectionFromCoordinate (_ fromLoc : CLLocationCoordinate2D , toLoc : CLLocationCoordinate2D) -> Double {
let fLat = degreesToRadians(degrees: fromLoc.latitude)
let fLng = degreesToRadians(degrees: fromLoc.longitude)
let tLat = degreesToRadians(degrees: toLoc.latitude)
let tLng = degreesToRadians(degrees: toLoc.latitude)
let degree = radiansToDegrees(radians: atan2(sin(tLng-fLng) * cos(tLat), cos(fLat)*sin(tLat)-sin(fLat)*cos(tLat)*cos(tLng-fLng)))
if (degree >= 0) {
return degree
} else {
return 360.0 + degree
}
}
//--------------------------------------------------
//MARK:
//MARK: - View Life Cycle Methods
//--------------------------------------------------
override func viewDidLoad() {
super.viewDidLoad()
//Configure Custom Annotation and Add to CustomAnnotation View
pointAnnotation = CarCustomAnnotation()
pointAnnotation.pinCustomImageName = "car"
pointAnnotation.coordinate = sourceCoordinate!
pinAnnotationView = MKAnnotationView(annotation: pointAnnotation, reuseIdentifier: reuseIdentifier)
//Set MapView for Showing Car Pin Annotation to One Region
mapView.delegate = self
mapView.addAnnotation(pinAnnotationView.annotation!)
mapView.setCenter(sourceCoordinate!, animated: true)
mapView.setRegion(MKCoordinateRegionMakeWithDistance(sourceCoordinate!, 140, 140), animated: true)
}
}
extension ViewController : MKMapViewDelegate {
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
if overlay is MKPolyline {
let polylineRenderer = MKPolylineRenderer(overlay: overlay)
polylineRenderer.strokeColor = UIColor.blue
polylineRenderer.lineWidth = 4.0
return polylineRenderer
}
return MKOverlayRenderer()
}
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
var annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: reuseIdentifier)
if annotationView == nil {
annotationView = MKAnnotationView(annotation: annotationView?.annotation, reuseIdentifier: reuseIdentifier)
annotationView?.canShowCallout = false
} else {
annotationView?.annotation = annotation
annotationView?.canShowCallout = false
}
annotationView?.image = UIImage.init(named:pointAnnotation.pinCustomImageName)
return annotationView
}
func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView) {
//Set PolyLine Between Source and Destinattion
let polyline = MKPolyline(coordinates: [sourceCoordinate!,destinationCoordinate!], count: 2)
mapView.add(polyline)
pointAnnotation.courseDegrees = self.getHeadingForDirectionFromCoordinate(sourceCoordinate!, toLoc: destinationCoordinate!)
view.transform = CGAffineTransform(rotationAngle:CGFloat(pointAnnotation.courseDegrees))
self.moveCar(self.destinationCoordinate!)
}
//Inert Animation Duration and Destination Coordinate which you are getting from server.
func moveCar(_ destinationCoordinate : CLLocationCoordinate2D) {
UIView.animate(withDuration: 20, animations: {
self.pointAnnotation.coordinate = destinationCoordinate
}, completion: { success in
if success {
// handle a successfully ended animation
self.resetCarPosition()
} else {
// handle a canceled animation, i.e move to destination immediately
self.pointAnnotation.coordinate = destinationCoordinate
}
})
}
func resetCarPosition() {
self.pointAnnotation.courseDegrees = 0.0
self.mapView.remove(self.mapView.overlays[0])
self.pinAnnotationView.transform = CGAffineTransform(rotationAngle:CGFloat(pointAnnotation.courseDegrees))
self.pointAnnotation.coordinate = self.sourceCoordinate!
}
}
CarCustomAnnotation
import UIKit
import MapKit
class CarCustomAnnotation: MKPointAnnotation {
var pinCustomImageName:String!
var courseDegrees : Double! // Change The Value for Rotating Car Image Position
}
MarkerAnnotationView
import UIKit
import MapKit
class MarkerAnnotationView: MKAnnotationView {
override var annotation: MKAnnotation? {
willSet {
guard let annotation = newValue as? CarCustomAnnotation else { return }
image = UIImage.init(named: annotation.pinCustomImageName)
}
}
}
Also find working full demo using this link:https://www.dropbox.com/s/8x42mm9vmtoeovd/AnnotationMovingDemo.zip?dl=0
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…