如何自定义MKPolyLineView来绘制不同的样式线

我想自定义在MKMapView上绘制的线条以显示路线,以便线条具有边框颜色和填充颜色。 类似于它有一个黑色的边界,并充满了另一种颜色:

与黑色边框的蓝线

我目前只是从mapView:viewForOverlay:返回MKPolyLineView对象mapView:viewForOverlay:它适用于普通线条。 该文档说MKPolyLineView是不是被子类,所以我应该inheritanceMKOverlayView并实现我自己的drawMapRect? 或者,我应该inheritanceMKOverlayPathView? 或者创build一个替代MKPolylineView?

编辑 – 我问的是:在哪里放置自己的Quartz绘图代码,以绘制自己的注释/覆盖? 目前我已经创build了一个MKOverlayView的子类,并实现了我自己的drawMapRect:zoomScale:inContext:这样绘制叠加图很容易,但这是最好的解决scheme吗?

您可以通过实现您自己的MKOverlayPathView子类来完成此操作,该子类在地图矩形中绘制两次path。 一旦黑色变厚,另一种颜色再变薄一次。

我已经创build了一个简单的MKPolylineView的替代,它可以让你这样做: ASPolylineView 。

如果你想自己做,你需要实现的两个主要方法可能是这样的:

 - (void)drawMapRect:(MKMapRect)mapRect zoomScale:(MKZoomScale)zoomScale inContext:(CGContextRef)context { UIColor *darker = [UIColor blackColor]; CGFloat baseWidth = self.lineWidth / zoomScale; // draw the dark colour thicker CGContextAddPath(context, self.path); CGContextSetStrokeColorWithColor(context, darker.CGColor); CGContextSetLineWidth(context, baseWidth * 1.5); CGContextSetLineCap(context, self.lineCap); CGContextStrokePath(context); // now draw the stroke color with the regular width CGContextAddPath(context, self.path); CGContextSetStrokeColorWithColor(context, self.strokeColor.CGColor); CGContextSetLineWidth(context, baseWidth); CGContextSetLineCap(context, self.lineCap); CGContextStrokePath(context); [super drawMapRect:mapRect zoomScale:zoomScale inContext:context]; } - (void)createPath { // turn the polyline into a path CGMutablePathRef path = CGPathCreateMutable(); BOOL pathIsEmpty = YES; for (int i = 0; i < self.polyline.pointCount; i++) { CGPoint point = [self pointForMapPoint:self.polyline.points[i]]; if (pathIsEmpty) { CGPathMoveToPoint(path, nil, point.x, point.y); pathIsEmpty = NO; } else { CGPathAddLineToPoint(path, nil, point.x, point.y); } } self.path = path; } 

您可以添加两个具有相同坐标但厚度不同的MKPolyLineView对象。

将strokeColor设置为黑色,添加lineWidth为10(或其他)。

然后添加另一个lineWidth 6与strokeColor设置为您的其他所需的颜色。

您可以对两个MKPolyLineView对象使用相同的MKPolyLine。

MKPolylineView只能用于抚摸指定的path。 你可以使用MKOverlayPathView一些属性来改变它们的外观,但是只有其中的一些会被应用,例如fillColorstrokeColor

如果你想绘制更复杂的东西,你可以使用MKOverlayPathView 。 这是更通用的,因此不仅适用于抚摸path。 为了绘制简单的线条,结果将与MKPolylineView相同(至less根据文档)。

如果你想做更复杂的绘图,子类MKOverlayPathView 。 你想要做的是不平凡的。

我使用一个NamedOverlay子类,它包含一个名称为overlay的子类:

NamedOverlay.h

 #import <Foundation/Foundation.h> #import <MapKit/MapKit.h> @interface NamedOverlay : NSObject <MKOverlay> @property (strong, readonly, nonatomic) NSString *name; @property (strong, readonly, nonatomic) id<MKOverlay> overlay; -(id)initWithOverlay:(id<MKOverlay>)overlay andName:(NSString *)name; @end 

NamedOverlay.m

 #import "NamedOverlay.h" @implementation NamedOverlay - (id)initWithOverlay:(id<MKOverlay>)overlay andName:(NSString *)name { _name = name; _overlay = overlay; return self; } - (MKMapRect)boundingMapRect { return [_overlay boundingMapRect]; } - (CLLocationCoordinate2D)coordinate { return [_overlay coordinate]; } -(BOOL)intersectsMapRect:(MKMapRect)mapRect { return [_overlay intersectsMapRect:mapRect]; } @end 

并在地图控制器中实例化两个不同名称的叠加层,然后在MKMapViewDelegate我可以确定要绘制的叠加层,并执行如下操作:

 - (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id < MKOverlay >)overlay { NamedOverlay *namedOverlay = (NamedOverlay *) overlay; MKPolyline *polyline = namedOverlay.overlay; if ([namedOverlay.name isEqualToString:@"top"]) { MKPolylineView *view1 = [[MKPolylineView alloc] initWithOverlay:polyline]; view1.strokeColor = [UIColor whiteColor]; view1.lineWidth = 25.0; return view1; } else { MKPolylineView *view1 = [[MKPolylineView alloc] initWithOverlay:polyline]; view1.strokeColor = [UIColor blueColor]; view1.lineWidth = 15.0; return view1; } } 

我知道这可能不符合你想要的纯粹的方法,但为什么不使用MKPolygon而不是MKPolyLine
创build一个MKPolygon实例,该实例代表您的路线周围走廊 ,然后当您创build与您创build的MKPolygon /走廊对应的MKPolygonView时,设置MKPolygonView的属性以获取不同的填充颜色和strokeColor

  myPolygonView.lineWidth=3; myPolygonView.fillColor=[UIColor blueColor]; myPolygonView.strokeColor=[UIColor darkGrayColor]; 

我没有自己尝试,但这应该工作。 唯一的缺点是,当你放大/缩小时,'路线'的'宽度'将改变….:/