使用自定义注释移动动画IOS Swift喜欢Ola Uber App MapKit

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

在我的应用程序中,我每隔10秒从服务器接收一个位置,所以我想用动画从一点到另一点动画我的自定义注释。

我想在iOS Swift 3中使用MapKit移动注释如何将移动动画从一个位置移动到另一个位置。 我发送我的viewController类代码请仔细阅读并帮助我摆脱这个问题

谢谢

这里我是添加自定义注释

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

然后

 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 } 

而另一个function是

  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() } } } 

据我了解你的问题,我提出这个解决方案,其中我在两个位置之间画了一个polly直播,一旦用户点击该汽车注释汽车注释将在类似于优步的路径上运行。

您可以通过自定义方法moveCar(_ destinationCoordinate:CLLocationCoordinate2D)并传递从服务器获取的坐标的最新值来为自定义注释设置动画。

视图控制器

  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, ie 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) } } } 

还可以使用以下链接找到工作的完整演示: https : //www.dropbox.com/s/8x42mm9vmtoeovd/AnnotationMovingDemo.zip?dl = 0