如何自定义MKPolyLineView以绘制不同的样式线

时间:2011-10-14 12:28:35

标签: iphone ios cocoa-touch mkmapview overlay

我想自定义在MKMapView上绘制的线条以显示路线,以便线条具有边框颜色和填充颜色。与此类似,它有一个黑色边框,并填充另一种颜色:

blue line with black border

我目前正在从mapView:viewForOverlay:返回MKPolyLineView对象,这对于普通线路工作正常。文档说MKPolyLineView不是子类,所以我应该继承MKOverlayView并实现我自己的drawMapRect?或者我应该继承MKOverlayPathView?或者创建MKPolylineView的替代品?

编辑 - 我要问的是:在哪里放置自己的Quartz绘图代码以绘制自己的注释/叠加层?目前我已经创建了MKOverlayView的子类并实现了我自己的drawMapRect:zoomScale:inContext:以这种方式绘制叠加层非常容易,但这是最好的解决方案吗?

5 个答案:

答案 0 :(得分:12)

您可以通过实现自己的MKOverlayPathView子类来完成此操作,该子类在map rect中绘制两次路径。一旦用黑色加厚,一次用更薄的颜色加上另一种颜色。

我已经创建了一个简单的替换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;
}

答案 1 :(得分:4)

您可以添加两个具有相同坐标但厚度不同的MKPolyLineView对象。

使用lineColor设置为黑色添加lineWidth为10(或其他)的一个。

然后添加另一个lineWidth为6,并将strokeColor设置为您想要的其他颜色。

您可以对MKPolyLineView对象使用相同的MKPolyLine。

答案 2 :(得分:2)

MKPolylineView只能用于抚摸指定的路径。您可以使用MKOverlayPathView中的某些属性来更改其外观,但只会应用其中一些属性,例如fillColorstrokeColor

如果您想绘制更复杂的内容,可以使用MKOverlayPathView。它更通用,因此不仅适用于抚摸路径。对于绘制简单线条,结果将与MKPolylineView相同(至少,根据文档)。

如果你想做更复杂的绘图,子类MKOverlayPathView。你要做的事情并非无足轻重。

答案 3 :(得分:2)

我使用一个子类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;
    }
}

答案 4 :(得分:1)

我知道这可能与您想要的纯方法不符,但为什么不使用MKPolygon代替MKPolyLine呢? 创建一个MKPolygon实例,代表路径周围的 走廊 ,然后,当您创建与MKPolygon /对应的MKPolygonView时你创建的走廊,设置MKPolygonView的属性以获得不同的填充颜色和strokeColor

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

我自己没有尝试,但这应该有效。唯一的缺点是,当您放大/缩小时,“路线”的“宽度”将改变....:/