2013-02-16 237 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