I have a mapview as shown below
The lines drawn in the map are using MKPolyline. I have used apple MapKit framework to display my map. My requirement is when the user selects the annotation on Polyline, the polyline should show direction as shown below
How can I show the animation in my map view? MKOverlayRenderer inherits from NSObject, It is not possible to animate using UIView Animation. I found some link here , its in objective C for iOS 7, IS it possible in swift to do the same?
MKOverlayRender inherits from NSObject. So it is not possible to add CAlayer to MKOverlayRenderer as explained in this sample project. The steps I followed to get the following animation effect are
Subclass MKOverlayRenderer and add a custom image as overlay on the map
class MapOverlayView: MKOverlayRenderer {
var overlayImage: UIImage
var angle: CGFloat
init(overlay: MKOverlay, overlayImage:UIImage, angle: CGFloat) {
self.overlayImage = overlayImage
self.angle = angle
super.init(overlay: overlay)
}
override func draw(_ mapRect: MKMapRect, zoomScale: MKZoomScale, in context: CGContext) {
let mapImage = overlayImage.cgImage
let mapRect = rect(for: overlay.boundingMapRect)
// Calculate centre point on which image should be rotated
let centerPoint = CGPoint(x: mapRect.midX, y: mapRect.midY)
let a = sqrt(pow(centerPoint.x, 2.0) + pow(centerPoint.y, 2.0))
let sub1 = (centerPoint.y / a) * cos(angle / 2.0)
let sub2 = (centerPoint.x / a) * sin(angle / 2.0)
let deltaX = -2 * a * sin((0 - angle) / 2.0) * (sub1 + sub2)
let sub3 = (centerPoint.x / a) * cos(angle / 2.0)
let sub4 = (centerPoint.y / a) * sin(angle / 2.0)
let deltaY = 2 * a * sin((0 - angle) / 2.0) * (sub3 - sub4)
context.translateBy(x: deltaX, y: deltaY)
context.rotate(by: angle)
context.draw(mapImage!, in: mapRect)
}
}
class MapOverlay: NSObject, MKOverlay {
var coordinate: CLLocationCoordinate2D
var boundingMapRect: MKMapRect
var identifier: String?
init(identifier:String, coord: CLLocationCoordinate2D, rect: MKMapRect) {
self.coordinate = coord
self.boundingMapRect = rect
self.identifier = identifier
}
}
Call a timer to change alpha value of added overlays
var timer = Timer() timer = Timer.scheduledTimer(timeInterval: 0.1, target: self, selector: #selector(self.toggle), userInfo: nil, repeats: true)
Function to change alpha of overlay renderer
func changeAlphaValue(identifier: String) {
let overlays = self.mapView.overlays
let tag: String = identifier
for overlay in overlays {
if let overlay = overlay as? MapOverlay {
let identifier = overlay.identifier
if identifier == tag {
let renderer = mapView.renderer(for: overlay)
DispatchQueue.main.async{
renderer?.alpha = 1.0
}
}
else {
let renderer = mapView.renderer(for: overlay)
DispatchQueue.main.async{
renderer?.alpha = 0.0
}
}
}
}
}
This will give the following animation on map
The project is available on GitHub - link