как настроить MKPolyLineView для рисования линий разных стилей - PullRequest
9 голосов
/ 14 октября 2011

Я хочу настроить линии, нарисованные в MKMapView, чтобы показать маршрут, чтобы линии имели цвет границы и цвет заливки.Аналогично этому, когда он имеет черную рамку и заполнен другим цветом:

blue line with black border

В настоящее время я просто возвращаю объекты MKPolyLineView из mapView:viewForOverlay:, что прекрасно работает для простых линий.В документах говорится, что MKPolyLineView не должен быть разделен на подклассы, поэтому я должен создать подкласс MKOverlayView и реализовать свой собственный drawMapRect?Или я должен подкласс MKOverlayPathView?Или создать замену для MKPolylineView?

РЕДАКТИРОВАТЬ - я спрашиваю: где находится место, где можно разместить свой собственный код для рисования в Кварце, чтобы рисовать свои собственные аннотации / наложения?В настоящее время я создал подкласс MKOverlayView и реализую свой собственный drawMapRect: zoomScale: inContext: Рисовать оверлей довольно просто, но это лучшее решение?

Ответы [ 5 ]

12 голосов
/ 21 февраля 2013

Вы можете сделать это, внедрив собственный подкласс MKOverlayPathView, который дважды рисует путь в прямоугольнике карты.Один раз толще с черным, а другой тоньше с другим цветом.

Я создал простую замену 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;
}
4 голосов
/ 21 октября 2011

Вы можете просто добавить два объекта MKPolyLineView с одинаковыми координатами, но разной толщины.

Добавьте один с шириной строки 10 (или любой другой) с установленным черным штрихом.

Затем добавьте еще один с lineWidth 6, с strokeColor, установленным на ваш другой желаемый цвет.

Вы можете использовать один и тот же MKPolyLine для обоих объектов MKPolyLineView.

2 голосов
/ 15 марта 2014

Я использую подкласс NamedOverlay, который содержит оверлейное имя:

NamedOverlay.h

#import <Foundation/Foundation.h>
#import <MapKit/MapKit.h>

@interface NamedOverlay : NSObject <MKOverlay>

@property (strong, readonly, nonatomic) NSString *name;
@property (strong, readonly, nonatomic) id<MKOverlay> overlay;

-(id)initWithOverlay:(id<MKOverlay>)overlay andName:(NSString *)name;

@end

NamedOverlay.m

#import "NamedOverlay.h"

@implementation NamedOverlay

- (id)initWithOverlay:(id<MKOverlay>)overlay andName:(NSString *)name
{
    _name = name;
    _overlay = overlay;
    return self;
}

- (MKMapRect)boundingMapRect
{
    return [_overlay boundingMapRect];
}

- (CLLocationCoordinate2D)coordinate
{
    return [_overlay coordinate];
}

-(BOOL)intersectsMapRect:(MKMapRect)mapRect
{
    return [_overlay intersectsMapRect:mapRect];
}

@end

и на картеКонтроллер Я создаю два оверлея с разными именами, затем в MKMapViewDelegate я могу определить, какой оверлей я хочу нарисовать, и сделать что-то вроде:

- (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id < MKOverlay >)overlay
{
    NamedOverlay *namedOverlay = (NamedOverlay *) overlay;
    MKPolyline *polyline = namedOverlay.overlay;
    if ([namedOverlay.name isEqualToString:@"top"]) {
        MKPolylineView *view1 = [[MKPolylineView alloc] initWithOverlay:polyline];
        view1.strokeColor = [UIColor whiteColor];
        view1.lineWidth = 25.0;
        return view1;
    } else {
        MKPolylineView *view1 = [[MKPolylineView alloc] initWithOverlay:polyline];
        view1.strokeColor = [UIColor blueColor];
        view1.lineWidth = 15.0;
        return view1;
    }
}
2 голосов
/ 25 октября 2011

MKPolylineView можно использовать только для обводки указанного пути. Вы можете использовать некоторые свойства в MKOverlayPathView, чтобы изменить их внешний вид, но применимы только некоторые из них, например fillColor, strokeColor.

Если вы хотите нарисовать что-то более сложное, вы можете использовать MKOverlayPathView. Он более универсален и поэтому подходит не только для поглаживания. Для рисования простых линий результат будет идентичен MKPolylineView (по крайней мере, согласно документам).

Если вы хотите сделать более сложное рисование, подкласс MKOverlayPathView. То, что вы пытаетесь сделать, нетривиально.

1 голос
/ 20 октября 2011

Я знаю, что это может не соответствовать чистому подходу, который вы хотите, но почему бы не использовать MKPolygon вместо MKPolyLine?
Создать экземпляр MKPolygon, который представляет собой вид коридор вокруг вашего маршрута , а затем, когда вы создаете MKPolygonView, который соответствует созданному вами MKPolygon / коридору, установите свойства MKPolygonView, чтобы получить другой цвет заливки и strokeColor

  myPolygonView.lineWidth=3;
  myPolygonView.fillColor=[UIColor blueColor];
  myPolygonView.strokeColor=[UIColor darkGrayColor];

Я сам не пробовал, но это должно сработать.Единственным недостатком является то, что при увеличении / уменьшении «ширина» «маршрута» изменится ....: /

...