2013-02-16 3 views
5

Я пытаюсь нарисовать хороший MKPolyline на MKPolylineView. Все идет отлично до сих пор - ломаная рисует так же, как я хочу его, и когда я хочу его, используя следующий код:Draw MKPolyline Fill Color

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

В результате я получаю линию с сплошным синим цветом. Синий, я вижу, однако, не цвет заливки с тактом, который я ожидаю - это синий цвет штриха. Когда я использую этот метод, цвет заливки отсутствует. Почему он не рисует цвет заливки на полилинии?

После дальнейшего изучения, я нашел эту пикантную информацию в Quick Help разделе Xcode :

Класс MKPolylineView обеспечивает визуальное представление для объекта аннотаций MKPolyline. Этот вид гласит путь, представленный аннотацией. (Этот класс не заполняет область, заключенную в путь.) Вы можете изменить цвет и другие атрибуты чертежа пути, изменив свойства, унаследованные от класса MKOverlayPathView.

Это просто звучит нелепо. Я должен использовать этот класс для set цвет заливки, но я не могу использовать этот класс для draw цвет заливки? Это кажется очень странным, учитывая, что он уже рисует удар. Последняя строка в этом объяснении из документации немного неясна, но, кажется, дает ответ - мне просто сложно кодировать/находить ответ. У меня нет MKOverlayPathView в моем проекте (что это такое?), Но кажется, что это решение - кто-нибудь знает, как его использовать?

+0

'MKPolylineView' является подклассом' MKOverlayPathView'. Независимо от того, вы просто хотите использовать 'MKPolygon' (и создать связанный' MKPolygonView') вместо 'MKPolyline'. 'MKPolygon' рисует как удар, так и заливку. – Rob

ответ

15

Если вы хотите линию одного цвета и заливку другого, используйте MKPolygon вместо MKPolyline. Поэтому соответствующим образом измените свое первоначальное создание аннотации. И тогда вы измените ваш viewForOverlay (или, для прошивкой 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+), который будет обрабатывать MKPolygon, MKPolyline и MKCircle наложений:

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

У меня есть другой метод.

Если у вас нет массива координат, вы можете нарисовать две полилинии.

Нарисуйте первую строку вашей конкретной линии1_width и после этого нарисуйте другую строку с помощью line2_width = line1_width - 1.0.

Это будет рисовать две линии, а на второй строке вы увидите только ее маржу, став штрихом для первой линии.

1

Да, как сказал Роб, используйте MKPolygon и MKPolygonRenderer вместо MKPolyline и MKPolylineRenderer, но также убедитесь, что ваш массив точек находится в порядке по часовой стрелке. Если он находится в порядке против часовой стрелки, вам просто нужно отменить его, вызвав 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