2013-02-16 233 views
5

我试图在一个MKPolylineView画出一个漂亮的MKPolyline。一切都进行得很顺利,到目前为止 - 折线画就像我希望它时,我希望它用下面的代码:绘制MKPolyline填充颜色

[[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

'MKPolylineView'是MKOverlayPathView'的'的子类。无论如何,你只是想使用'MKPolygon'(并创建相关的'MKPolygonView')而不是'MKPolyline'。 'MKPolygon'绘制中风和填充。 – Rob 2013-02-16 22:44:55

回答

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(iOS版之前的版本7.0)和rendererForOverlay(iOS的7+),将处理MKPolygonMKPolylineMKCircle覆盖:

// 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; 
    } 

    if ([overlay isKindOfClass:[MKCircle class]]) 
    { 
     MKCircleRenderer *renderer = [[MKCircleRenderer alloc] initWithCircle:overlay]; 

     renderer.fillColor = [[UIColor cyanColor] colorWithAlphaComponent:0.2]; 
     renderer.strokeColor = [[UIColor blueColor] colorWithAlphaComponent:0.7]; 
     renderer.lineWidth = 3; 

     return renderer; 
    } 

    if ([overlay isKindOfClass:[MKPolyline class]]) 
    { 
     MKPolylineRenderer *renderer = [[MKPolylineRenderer alloc] initWithPolyline:overlay]; 

     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; 
    } 

    if ([overlay isKindOfClass:[MKCircle class]]) 
    { 
     MKCircleView *overlayView = [[MKCircleView alloc] initWithCircle:overlay]; 

     overlayView.fillColor  = [[UIColor cyanColor] colorWithAlphaComponent:0.2]; 
     overlayView.strokeColor = [[UIColor blueColor] colorWithAlphaComponent:0.7]; 
     overlayView.lineWidth  = 3; 

     return overlayView; 
    } 

    if ([overlay isKindOfClass:[MKPolyline class]]) 
    { 
     MKPolylineView *overlayView = [[MKPolylineView alloc] initWithPolyline:overlay]; 

     overlayView.strokeColor  = [[UIColor blueColor] colorWithAlphaComponent:0.7]; 
     overlayView.lineWidth  = 3; 

     return overlayView; 
    } 

    return nil; 
} 

这样我可以将这三种类型的叠加层添加到我的地图中,并且可以正确渲染它们。

1

我得到了另一种方法。

如果你没有一个坐标阵列可以绘制两条折线。

画出你的具体line1_width的第一道防线,之后绘制line2_width = line1_width其他线路 - 1.0。

这将引起两行,第二行,你会看到只有它的利润率,成为第一线的行程。

1

是作为罗布提到的,使用MKPolygon和MKPolygonRenderer代替MKPolyline和MKPolylineRenderer,还请确保您的点阵列是顺时针的顺序。如果它是逆时针顺序的,你只需要通过调用array()中的reverse()来反转它。

pointsToUse.reverse() 
let overlay = MKPolygon(coordinates: &pointsToUse, count: pointsToUse.count) 
1
You can do this by implementing your own MKOverlayPathView subclass, which draws the path twice in the map rect. Once thicker with black and once thinner on top with another colour. 

I have created a simple drop-in replacement of MKPolylineView which lets you do that: 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; 
} 

Or you can download code for it from below link 
https://github.com/nighthawk/ASPolylineView 

I have used it and have a look on this screen shot. 

Border color of polyline