如何为 Mapview iOS 中添加的 MKOverlayRenderer 设置动画?
How to animate MKOverlayRenderer added in Mapview iOS?
我有一个地图视图,如下所示
地图中绘制的线条使用的是MKPolyline。我使用苹果 MapKit 框架来显示我的地图。我的要求是当用户在 Polyline 上选择注释时,折线应显示如下所示的方向
如何在我的地图视图中显示动画? MKOverlayRenderer 继承自 NSObject,无法使用 UIView Animation 进行动画处理。我找到了一些 link here ,它在 objective C 中用于 iOS 7,是否可以在 swift 中做同样的事情?
https://github.com/jhurray/iOS7AnimatedMapOverlay
以上 link 对您有用 或以下代码。
- (void)mapView:(MKMapView *)mapView didAddOverlayRenderers:(NSArray *)renderers
{
// Iterate through all overlayRenderers
for (MKOverlayRenderer *overlayRenderer in renderers)
{
// MKPolylineRenderer
// Animate a 'fade'
if ([overlayRenderer isKindOfClass:[MKPolylineRenderer class]])
{
// Get MKPolylineRenderer
MKPolylineRenderer *polylineRenderer = (MKPolylineRenderer *)overlayRenderer;
// Let's manually set alpha to 0
polylineRenderer.alpha = 0.0f;
// Animate it back to 1
dispatch_async(dispatch_get_main_queue(), ^{
[UIView animateWithDuration:0.4 animations:^{
polylineRenderer.alpha = 1.0f
}];
});
}
}
}
谢谢
MKOverlayRender 继承自NSObject。因此,无法按照 sample project 中的说明将 CAlayer 添加到 MKOverlayRenderer。我得到以下动画效果的步骤是
Subclass MKOverlayRenderer 并添加自定义图像作为地图上的叠加层
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
}
}
调用计时器来更改添加的叠加层的 alpha 值
var 计时器 = 计时器 ()
timer = Timer.scheduledTimer(timeInterval: 0.1, target: self, selector: #selector(self.toggle), userInfo: nil, repeats: true)
更改叠加渲染器的 alpha 的函数
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
}
}
}
}
}
这将在地图上显示以下动画
该项目可在 GitHub - link
我有一个地图视图,如下所示
地图中绘制的线条使用的是MKPolyline。我使用苹果 MapKit 框架来显示我的地图。我的要求是当用户在 Polyline 上选择注释时,折线应显示如下所示的方向
如何在我的地图视图中显示动画? MKOverlayRenderer 继承自 NSObject,无法使用 UIView Animation 进行动画处理。我找到了一些 link here ,它在 objective C 中用于 iOS 7,是否可以在 swift 中做同样的事情?
https://github.com/jhurray/iOS7AnimatedMapOverlay
以上 link 对您有用 或以下代码。
- (void)mapView:(MKMapView *)mapView didAddOverlayRenderers:(NSArray *)renderers
{
// Iterate through all overlayRenderers
for (MKOverlayRenderer *overlayRenderer in renderers)
{
// MKPolylineRenderer
// Animate a 'fade'
if ([overlayRenderer isKindOfClass:[MKPolylineRenderer class]])
{
// Get MKPolylineRenderer
MKPolylineRenderer *polylineRenderer = (MKPolylineRenderer *)overlayRenderer;
// Let's manually set alpha to 0
polylineRenderer.alpha = 0.0f;
// Animate it back to 1
dispatch_async(dispatch_get_main_queue(), ^{
[UIView animateWithDuration:0.4 animations:^{
polylineRenderer.alpha = 1.0f
}];
});
}
}
}
谢谢
MKOverlayRender 继承自NSObject。因此,无法按照 sample project 中的说明将 CAlayer 添加到 MKOverlayRenderer。我得到以下动画效果的步骤是
Subclass MKOverlayRenderer 并添加自定义图像作为地图上的叠加层
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 }
}
调用计时器来更改添加的叠加层的 alpha 值
var 计时器 = 计时器 () timer = Timer.scheduledTimer(timeInterval: 0.1, target: self, selector: #selector(self.toggle), userInfo: nil, repeats: true)
更改叠加渲染器的 alpha 的函数
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
}
}
}
}
}
这将在地图上显示以下动画
该项目可在 GitHub - link