Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
488 views
in Technique[技术] by (71.8m points)

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

**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 to animate my custom annotation with animation from one point to another point.

I want to move annotation with MapKit in iOS Swift 3 how to give the move animation from one location to another. I sending my viewController class code please read carefully and help me to get out from this

thanks

Here I am Adding custom annotation

var point : MyCustomAnnotation?
   point = MyCustomAnnotation(coordinate:   CLLocationCoordinate2D(latitude: self.latitude , longitude: self.longitude ))
     point?.speed     = speed
     point?.dateTime  = time
     self.mapView.addAnnotation(point!)

After Than

func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {

    if annotation is MKUserLocation
    {
        return nil
    }
    UIView.animate(withDuration: 3)  {
        if(self.annotationView != nil )
        {


            self.annotationView?.removeFromSuperview()
        }else{

        }
        self.annotationView = self.mapView.dequeueReusableAnnotationView(withIdentifier: "Pin")
        if self.annotationView == nil{


            self.annotationView = AnnotationView(annotation: annotation, reuseIdentifier: "Pin")


            self.annotationView?.image = self.imagePin! 

            self.annotationView?.canShowCallout = false
        }else{
            self.annotationView?.annotation = annotation
        }

            let roatet =    CLLocation(latitude: self.latitude, longitude: self.longitude)
            .bearingToLocationDegrees(destinationLocation: CLLocation(latitude: self.rotLat, longitude: self.rotLng))


        self.rotLat = self.latitude
        self.rotLng = self.longitude

        self.annotationView?.image = self.imagePin?.imageRotatedByDegrees(oldImage: self.imagePin!, deg: CGFloat(roatet))


    return annotationView
}

And another function is

  func mapView(_ mapView: MKMapView,
                 didSelect view: MKAnnotationView)
    {
        // 1
        if view.annotation is MKUserLocation
        {
            // Don't proceed with custom callout
            return
        }
        // 2
        let starbucksAnnotation = view.annotation as! StarbucksAnnotation
        let views = Bundle.main.loadNibNamed("CustomCalloutView", owner: nil, options: nil)
        let calloutView = views?[0] as! CustomCalloutView
        calloutView.lbAc.text = starbucksAnnotation.acV
        calloutView.lbFuel.text = starbucksAnnotation.fuelV + "%"
        calloutView.lbPower.text = starbucksAnnotation.powerV
        calloutView.lbIgnation.text = starbucksAnnotation.ignitionV
        calloutView.lbBattery.text = starbucksAnnotation.battry
        calloutView.lbDate.text = starbucksAnnotation.dateTime

        calloutView.center = CGPoint(x: view.bounds.size.width / 2, y: -calloutView.bounds.size.height*0.52)
        view.addSubview(calloutView)
      //  UIView.animate(withDuration: 5) {
           mapView.setCenter((view.annotation?.coordinate)!, animated: true)
       // }

    }
    func mapView(_ mapView: MKMapView, didDeselect view: MKAnnotationView) {
        if view.isKind(of: AnnotationView.self)
        {
            for subview in view.subviews
            {
                subview.removeFromSuperview()
            }
        }
    }
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...