Reputation: 2244
**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()
}
}
}
Upvotes: 3
Views: 3697
Reputation:
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
Upvotes: 3