我有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;
}
就像“tile”一样,该线条隐藏了从MKTileOverlay
加载的图块。我怎么能:
- 指定MKPolyline
叠加层必须是透明的吗?
- 重新加载背景图块?
Screeshot:
See the tile with line has no background anymore http://sigmanet.ch/tmp/screen.png
答案 0 :(得分:4)
经过几天的工作,这是我自己的解决方案。
扩展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:
方法不会产生图块。
此代码会生效,当没有要渲染的背景图块时,路径也不会绘制。
答案 1 :(得分:1)
您必须子类化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,我只是发布了一个快速准备复制/粘贴新手的代码。