2013-02-16 6 views
5

Ich versuche, eine nette MKPolyline auf einem MKPolylineView zu zeichnen. Alles läuft großartig, so weit - die Polylinie zieht, so wie ich es will und wenn ich es möchte mit dem folgenden Code:Zeichnen MKPolyline Füllfarbe

[[self map] addOverlay:routeLine]; 

Und diese Methode, um die App zu sagen, wie es zeichnen:

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

Als Ergebnis bekomme ich eine Linie mit einem festen Blau. Das Blau, das ich sehe, ist jedoch nicht die Füllfarbe mit dem Strich, den ich erwarte - es ist das Blau der Strichfarbe. Es gibt keine Füllfarbe, wenn ich diese Methode verwende. Warum zeichnet es nicht die Füllfarbe auf der Polylinie?

Nach der Untersuchung weiter, fand ich diese Leckerbissen der Informationen in dem Schnellen Hilfe Abschnitt von Xcode:

Die MKPolylineView Klasse, um die visuelle Darstellung für eine MKPolyline Annotierungsobjekt bietet. Diese Ansicht streicht den Pfad, der von der Annotation dargestellt wird. (Diese Klasse füllt nicht den durch den Pfad eingeschlossenen Bereich.) Sie können die Farbe und andere Zeichenattribute des Pfads ändern, indem Sie die von der MKOverlayPathView-Klasse geerbten Eigenschaften ändern.

Das klingt einfach lächerlich. Ich muss diese Klasse zu Set die Füllfarbe verwenden, aber ich kann nicht diese Klasse zu zeichnen die Füllfarbe? Das scheint sehr merkwürdig, wenn man bedenkt, dass es schon den Strich zieht. Die letzte Zeile in dieser Erklärung aus der Dokumentation ist ein wenig unklar, scheint aber eine Antwort zu liefern - ich habe nur eine harte Zeit, die Antwort zu kodieren/zu finden. Ich habe kein MKOverlayPathView in meinem Projekt (was ist das überhaupt?) Aber scheint es die Lösung zu sein - weiß jemand, wie man es benutzt?

+0

'MKPolylineView' ist eine Unterklasse von' MKOverlayPathView'. Unabhängig davon, möchten Sie nur 'MKPolygon' (und erstellen Sie die zugehörige' MKPolygonView') anstelle von 'MKPolyline'. 'MKPolygon' zeichnet sowohl den Strich als auch die Füllung. – Rob

Antwort

15

Wenn Sie eine Zeile mit einer Farbe und eine Füllung mit einer anderen Farbe wünschen, verwenden Sie eine MKPolygon anstelle einer MKPolyline. Ändern Sie also Ihre ursprüngliche Erstellung der Annotation entsprechend. Und dann ändern Sie Ihre viewForOverlay (oder für iOS 7, rendererForOverlay) die MKPolygon zu erkennen und etwas tun, wie folgt aus:

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

Hinweis, Sie brauchen hier nicht alle Ihre Klasseneigenschaften zu referenzieren, wie Das Overlay wird an Ihre viewForOverlay übergeben. Dies ist ein wenig flexibler für den Fall, dass Sie mehrere Overlays zu Ihrer Karte hinzugefügt haben.


übrigens das sind meine Standard viewForOverlay (iOS-Versionen vor 7.0) und rendererForOverlay (iOS 7+), die MKPolygon behandelt, MKPolyline und MKCircle Overlays:

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

So kann ich Ich kann so viele dieser drei Arten von Überlagerungen zu meiner Karte hinzufügen und sie alle richtig darstellen.

1

Ich habe eine andere Methode.

Wenn Sie kein Koordinaten-Array haben, können Sie zwei Polylinien zeichnen.

Zeichnen Sie eine erste Zeile Ihrer spezifischen line1_width und danach die andere Zeile mit line2_width = line1_width - 1.0.

Dies wird zwei Linien zeichnen, und der zweiten Zeile sehen Sie nur seinen Rand, der Strich für die erste Zeile wird.

1

Ja, wie Rob erwähnt, verwenden Sie MKPolygon und MKPolygonRenderer anstelle eines MKPolyline und MKPolylineRenderer, aber stellen Sie auch sicher, dass Ihr Punktemuster im Uhrzeigersinn angeordnet ist. Wenn es gegen den Uhrzeigersinn ist, müssen Sie es nur umkehren, indem Sie reverse() auf dem Array aufrufen.

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

Verwandte Themen