7

私はに素敵な絵を描くことを試みてMKPolylineMKPolylineViewます。これまでのところ、すべてが順調に進んでいます。ポリラインは、次のコードを使用して、希望どおりに描画します。

[[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(とにかくそれは何ですか?)が、それは解決策のようです-誰かがそれを使用する方法を知っていますか?

4

4 に答える 4

16

ある色の線と別の色の塗りつぶしが必要な場合は、のMKPolygon代わりにを使用しMKPolylineます。したがって、それに応じて注釈の元の作成を変更します。次に、を認識して次のようなことを行うようにviewForOverlay(または、iOS 7の場合は)を変更します。rendererForOverlayMKPolygon

// 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(7.0より前のiOSバージョン)と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;
}

このようにして、これら3種類のオーバーレイをマップにいくつでも追加でき、それらすべてを適切にレンダリングできます。

于 2013-02-16T22:21:58.107 に答える
2

これを行うには、独自のMKOverlayPathViewサブクラスを実装します。これにより、マップrectにパスが2回描画されます。黒で厚くなり、別の色で上を薄くします。

私はそれを可能にする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;
}

または、以下のリンクhttps://github.com/nighthawk/ASPolylineViewからコードをダウンロードできます。

私はそれを使用して、このスクリーンショットを見てみました。

ポリラインの境界線の色

于 2017-03-10T10:04:57.660 に答える
1

別の方法があります。

座標配列がない場合は、2本のポリラインを描画できます。

特定のline1_widthの最初の線を描画し、その後、line2_width=line1_width-1.0でもう1本の線を描画します。

これにより2本の線が描画され、2番目の線のマージンのみが表示され、最初の線のストロークになります。

于 2014-05-28T14:06:32.050 に答える
1

はい、Robが述べたように、MKPolylineとMKPolylineRendererの代わりにMKPolygonとMKPolygonRendererを使用しますが、ポイントの配列が時計回りになっていることも確認してください。反時計回りの場合は、配列でreverse()を呼び出して逆にする必要があります。

pointsToUse.reverse()
let overlay = MKPolygon(coordinates: &pointsToUse, count: pointsToUse.count)
于 2016-10-18T23:22:46.897 に答える