move animation with custom annotation IOS Swift Like Ola Uber App MapKit

后端 未结 1 1190
时光说笑
时光说笑 2020-12-16 08:22

**Here the car image where I want to only rotate car icon.**

In my app I\'m receiving location from server in every 10 seconds so I want t

相关标签:
1条回答
  • 2020-12-16 09:01

    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

    0 讨论(0)
提交回复
热议问题