我有一个MKMapView
使用显示本地数据库中的磁贴的MKTileOverlay
。它工作正常。
然后我用MKDirections
来获取两个坐标之间的方向,并像这样绘制路线:
MKRoute *route = response.routes.lastObject;
MKPolyline *polyline = route.polyline;
// Draw path on overlay
[self.mapView insertOverlay:polyline aboveOverlay:self.tileOverlay];
但是当我缩放以查看该行时,它似乎没有磁贴背景(通常从MKTileOverlay
加载(存储到 self.tileOverlay
中))。我加入了一个图像,以便看得更清楚。
我还编写了以下代码来渲染叠加层:
- (MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id<MKOverlay>)overlay {
if ([overlay isKindOfClass:[MKTileOverlay class]]) {
return [[MKTileOverlayRenderer alloc] initWithTileOverlay:overlay];
}
else if ([overlay isKindOfClass:[MKPolyline class]]) {
MKPolylineRenderer *lineView = [[MKPolylineRenderer alloc] initWithOverlay:overlay];
lineView.strokeColor = [UIColor greenColor];
lineView.lineWidth = 3;
return lineView;
}
return nil;
}
这就像渲染线条的"瓷砖"隐藏了从MKTileOverlay
加载的瓷砖。我怎样才能 :
- 指定我MKPolyline
覆盖必须是透明的?
- 重新加载背景瓷砖?
斯克里肖特 :
看到带线条的瓷砖不再有背景 http://sigmanet.ch/tmp/screen.png
经过几天的工作,这是我自己的解决方案。
扩展MKPolylineRenderer
并添加对MKTileOverlayRenderer
的引用。我们称这个新类为MCPolylineRenderer
。
在此类中,重写以下两个方法:
- (void)drawMapRect:(MKMapRect)mapRect zoomScale:(MKZoomScale)zoomScale inContext:(CGContextRef)context {
// Draw path only if tile render has a tile
if ([self.tileRenderRef canDrawMapRect:mapRect zoomScale:zoomScale]) {
[super drawMapRect:mapRect zoomScale:zoomScale inContext:context];
}
}
- (BOOL)canDrawMapRect:(MKMapRect)mapRect zoomScale:(MKZoomScale)zoomScale {
// We can draw path only if tile render can also
return [self.tileRenderRef canDrawMapRect:mapRect zoomScale:zoomScale];
}
现在,在mapView:renderedForOverlay
方法中,将
MKPolylineRenderer *lineView = [[MKPolylineRenderer alloc] initWithOverlay:overlay];
跟
MCPolylineRenderer *lineView = [[MCPolylineRenderer alloc] initWithPolyline:overlay];
lineView.tileRenderRef = self.tileRender;
此外,还需要确保 loadTileAtPath:result:
方法不会在没有任何要呈现的内容(如"找不到磁贴"图像)时生成磁贴。
此代码将生效,当没有要呈现的背景磁贴时,也不会绘制路径。
您必须对 MKPolylineRenderer 进行子类化以同步渲染器绘制功能。
import Foundation
import MapKit
class MyPolylineRenderer: MKPolylineRenderer {
var tileRenderer: MKTileOverlayRenderer?
override func draw(_ mapRect: MKMapRect, zoomScale: MKZoomScale, in context: CGContext) {
if (tileRenderer?.canDraw(mapRect, zoomScale: zoomScale) ?? true) {
super.draw(mapRect, zoomScale: zoomScale, in: context)
}
}
override func canDraw(_ mapRect: MKMapRect, zoomScale: MKZoomScale) -> Bool {
return tileRenderer?.canDraw(mapRect, zoomScale: zoomScale) ?? super.canDraw(mapRect, zoomScale: zoomScale)
}
}
然后在您的MKMapViewDelegate
中,保留对 tileRenderer 的引用并实现rendererForOverlay
:
var tileRenderer: MKTileOverlayRenderer?
public func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
if let polyline = overlay as? MKPolyline {
let lineRenderer = NXPolylineRenderer(overlay: overlay)
lineRenderer.tileRenderer = tileRenderer
// Configure your polyline overlay renderer here...
return lineRenderer;
}
if let tileOverlay = overlay as? MKTileOverlay {
if tileRenderer == nil || tileRenderer.overlay != overlay {
tileRenderer = MKTileOverlayRenderer(overlay: overlay)
}
return tileRenderer
}
return MKOverlayRenderer(overlay: overlay)
}
这个想法的所有功劳都归@Jonathan,我只是发布了一个准备为新手复制/粘贴代码的 swift。