我正试图在MKPolyline
上绘制一个不错的MKPolylineView
。到目前为止,一切都很顺利 - 折线正如我想要的那样绘制,当我希望它使用以下代码时:
[[self map] addOverlay:routeLine];
这个方法告诉应用程序如何绘制它:
- (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id <MKOverlay>)overlay {
MKOverlayView* overlayView = nil;
self.routeLineView = [[MKPolylineView alloc] initWithPolyline:[self routeLine]];
[[self routeLineView] setFillColor:[UIColor colorWithRed:167/255.0f green:210/255.0f blue:244/255.0f alpha:1.0]];
[[self routeLineView] setStrokeColor:[UIColor colorWithRed:0/255.0f green:136/255.0f blue:255/255.0f alpha:1.0]];
[[self routeLineView] setLineWidth:15.0];
[[self routeLineView] setLineCap:kCGLineCapRound];
overlayView = [self routeLineView];
return overlayView;
}
结果我得到一条蓝色的线条。我看到的蓝色不是我期待的笔触的填充颜色 - 它是笔触颜色的蓝色。使用此方法时没有填充颜色。 为什么不在折线上绘制填充颜色?
在进一步调查之后,我在Xcode的快速帮助部分找到了这些信息:
MKPolylineView类提供MKPolyline注释对象的可视化表示。此视图描绘注释表示的路径。 (此类不会填充路径所包含的区域。)您可以通过修改从MKOverlayPathView类继承的属性来更改路径的颜色和其他绘图属性。
这听起来很荒谬。我必须使用这个类来设置填充颜色,但我不能使用这个类来绘制填充颜色?考虑到它已经引起了中风,这似乎很奇怪。文档中这个解释的最后一行有点不清楚,但似乎提供了答案 - 我只是很难编码/找到答案。我的项目中没有MKOverlayPathView
(无论如何都是这样?)但似乎是解决方案 - 有没有人知道如何使用它?
答案 0 :(得分:15)
如果您想要一种颜色的线条和另一种颜色的填充,请使用MKPolygon
而不是MKPolyline
。因此,相应地修改您的原始注释创建。然后,您修改viewForOverlay
(或者,对于iOS 7,rendererForOverlay
)以识别MKPolygon
并执行以下操作:
// for iOS7+; see `viewForOverlay` for earlier versions
- (MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id<MKOverlay>)overlay
{
if ([overlay isKindOfClass:[MKPolygon class]])
{
MKPolygonRenderer *renderer = [[MKPolygonRenderer alloc] initWithPolygon:overlay];
renderer.fillColor = [[UIColor cyanColor] colorWithAlphaComponent:0.2];
renderer.strokeColor = [[UIColor blueColor] colorWithAlphaComponent:0.7];
renderer.lineWidth = 3;
return renderer;
}
return nil;
}
// for iOS versions prior to 7; see `rendererForOverlay` for iOS7 and later
- (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id <MKOverlay>)overlay
{
if ([overlay isKindOfClass:[MKPolygon class]])
{
MKPolygonView *overlayView = [[MKPolygonView alloc] initWithPolygon:overlay];
overlayView.fillColor = [[UIColor cyanColor] colorWithAlphaComponent:0.2];
overlayView.strokeColor = [[UIColor blueColor] colorWithAlphaComponent:0.7];
overlayView.lineWidth = 3;
return overlayView;
}
return nil;
}
注意,您无需在此处引用任何类属性,因为叠加层会传递给您的viewForOverlay
。如果您在地图上添加了多个叠加层,则会更加灵活。
顺便提一下,这些是我的标准viewForOverlay
(7.0之前的iOS版本)和rendererForOverlay
(iOS 7+),它们将处理MKPolygon
,MKPolyline
和{ {1}}叠加:
MKCircle
通过这种方式,我可以在地图中添加这三种类型的叠加层,并且可以正确渲染所有叠加层。
答案 1 :(得分:2)
您可以通过实现自己的MKOverlayPathView子类来完成此操作,该子类在map rect中绘制两次路径。一旦用黑色加厚,一次用更薄的颜色加上另一种颜色。
我创建了一个简单的直接替代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;
}
或者您可以从以下链接https://github.com/nighthawk/ASPolylineView
下载代码我已经使用过了,看看这个屏幕截图。
答案 2 :(得分:1)
我有另一种方法。
如果您没有坐标数组,则可以绘制两条折线。
绘制特定line1_width的第一行,然后绘制另一行line2_width = line1_width - 1.0。
这将绘制两条线,而第二条线只会看到它的边距,成为第一条线的笔划。
答案 3 :(得分:1)
是的,正如Rob所说,使用MKPolygon和MKPolygonRenderer而不是MKPolyline和MKPolylineRenderer,但也要确保您的点数组按顺时针顺序排列。如果它是逆时针顺序,你只需要通过调用数组上的reverse()来反转它。
pointsToUse.reverse()
let overlay = MKPolygon(coordinates: &pointsToUse, count: pointsToUse.count)