【问题标题】:dynamically change lineWidth of mkpolyline动态改变 mkpolyline 的 lineWidth
【发布时间】:2015-01-06 21:06:51
【问题描述】:

我的应用程序中有地图,它根据用户位置移动。我已经成功地为源和目标绘制了一条折线。 使用以下代码

- (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id < MKOverlay >)overlay{
    
    MKPolylineView *view1 = [[MKPolylineView alloc] initWithOverlay:overlay];
    
        view1.lineWidth = 27.0;
        view1.strokeColor = [UIColor colorWithRed:55.0/255.0 green:168.0/255.0 blue:219.0/255.0 alpha:1];
   
    return view1;
}

但我的问题是当地图移动时,意味着我在用户移动时更改地图区域,然后有时折线显示不佳,有时显示比实际尺寸厚,如下图所示。

我附上下面的图片,请告诉我在地图移动时我可以为平滑折线做些什么。

编辑

正如马特建议的那样,我创建了一个 MKPolylineRenderer 的子类并实现 drawMapRect 方法,如下所示:

-(void)drawMapRect:(MKMapRect)mapRect zoomScale:(MKZoomScale)zoomScale inContext:(CGContextRef)context{
    
    
    CGMutablePathRef fullPath = CGPathCreateMutable();
    BOOL pathIsEmpty = YES;
    
    //merging all the points as entire path
    for (int i=0;i< self.polyline.pointCount;i++){
        CGPoint point = [self pointForMapPoint:self.polyline.points[i]];
        if (pathIsEmpty){
            CGPathMoveToPoint(fullPath, nil, point.x, point.y);
            pathIsEmpty = NO;
        } else {
            CGPathAddLineToPoint(fullPath, nil, point.x, point.y);
        }
    }
    
    //get bounding box out of entire path.
    CGRect pointsRect = CGPathGetBoundingBox(fullPath);
    CGRect mapRectCG = [self rectForMapRect:mapRect];
    //stop any drawing logic, cuz there is no path in current rect.
    if (!CGRectIntersectsRect(pointsRect, mapRectCG))return;
    
    UIColor *darker = [UIColor blackColor];
    CGFloat baseWidth = 10 / 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, [UIColor redColor].CGColor);
    CGContextSetLineWidth(context, baseWidth);
    CGContextSetLineCap(context, self.lineCap);
    CGContextStrokePath(context);
    
    [super drawMapRect:mapRect zoomScale:zoomScale inContext:context];
}

但同样的问题 见下图:

好的,我想我遇到了问题,我的折线添加了一次,但是随着用户的速度我改变了 MKMapView 的缩放级别,缩放级别也改变了,但是折线宽度没有刷新,

那么我如何动态改变 mkpolyline 的 lineWidth ??

【问题讨论】:

  • 在 iOS 10 中使用 MKPolylineRenderer 时出现同样的问题。您找到解决方案了吗?
  • 我遇到了同样的问题,还没有找到任何解决方案。
  • 我也面临同样的问题,任何解决方案都可以根据放大或缩小来管理折线宽度@Kumar
  • 在撰写本文时,iOS 11.3.1 没有找到有效的解决方案。我尝试了 StackOverflow 上建议的几种解决方案,但都没有奏效。有消息吗?

标签: ios mkmapview mkpolyline


【解决方案1】:

问题是您将lineWidth 设置为固定宽度(非常大的固定宽度)。随着地图放大或缩小,它会变大或变小。

相反,实现您自己的 MKOverlayRenderer 子类,并覆盖 drawMapRect:zoomScale:inContext:。它接收一个zoomScale 参数,因此您可以调整线条的宽度以更好地查看当前的比例。

【讨论】:

【解决方案2】:

子类 MKPolylineRenderer 并覆盖 applyStrokePropertiesToContext:atZoomScale: 以便它忽略比例,并以恒定宽度绘制线条:

@interface ConstantWidthPolylineRenderer : MKPolylineRenderer
@end

@implementation ConstantWidthPolylineRenderer

- (void)applyStrokePropertiesToContext:(CGContextRef)context
                           atZoomScale:(MKZoomScale)zoomScale
{
    [super applyStrokePropertiesToContext:context atZoomScale:zoomScale];
    CGContextSetLineWidth(context, self.lineWidth);
}

@end

现在使用它并欣赏它的流畅渲染:

- (MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id<MKOverlay>)overlay
{
    MKPolyline *polyline = (MKPolyline *)overlay;
    ConstantWidthPolylineRenderer *renderer = [[ConstantWidthPolylineRenderer alloc] initWithPolyline:polyline];
    renderer.strokeColor = [UIColor redColor];
    renderer.lineWidth = 40;
    return renderer;
}

【讨论】:

  • 谢谢!那行得通,但现在的问题是-当我放大或缩小时。线宽是等宽。这对我来说是个大问题。
  • 我不知道,伙计。也许您的自定义渲染器知道缩放级别?我相信你会弄清楚的。
  • 抱歉,我不确定如何管理缩放级别和宽度。但是我在该方法中尝试了很少的自定义,但是这些 lineWidth 更改重现了该线程中提出的相同问题。
  • @Kumar 你能找到根据缩小和放大设置 lineWidth 的解决方案吗?
【解决方案3】:

您需要使用MKPolylineRenderer 而不是MKPolylineView

- (MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id < MKOverlay >)overlay {
    @try {

        MKPolylineRenderer *renderer = [[[MKPolylineRenderer alloc] initWithOverlay:overlay];
        renderer.lineWidth = 27.0;
        renderer.strokeColor = [UIColor colorWithRed:55.0/255.0 green:168.0/255.0 blue:219.0/255.0 alpha:1];

        return renderer;
    }
    @catch (NSException *exception) {
        NSLog(@"exception :%@",exception.debugDescription);
    }
}

阅读这篇文章:

MKPolylineRenderer 类提供 MKPolyline 叠加对象的可视化表示。此渲染器仅描边;它没有填满它。您可以通过修改从父类继承的属性来更改多边形的颜色和其他绘图属性。您通常按原样使用此类,而不是对其进行子类化。

From Apple library

MKPolylineView 类为 MKPolyline 注释对象提供可视化表示。此视图描边由注释表示的路径。 (该类不填充路径包围的区域。)您可以通过修改继承自 MKOverlayPathView 类的属性来更改路径的颜色和其他绘制属性。此类通常按原样使用,而不是子类化。

From Apple library

【讨论】:

  • 感谢回复,但我也支持ios6,所以我使用了那个委托方法。
  • 我也用过这个 mkrenderer 但它也给了我同样的问题。
  • 是的。如果您要支持 iOS 6,则 MKOverlayRenderer 不可用。
  • 有没有其他方法可以快速绘制折线,意味着我已经看到很多使用 -()drawMethod(),但我还没有实现所以我不知道,你能告诉我这对我有帮助吗?
  • 好的,有没有其他方法可以根据缩放级别管理 lineWidth ?根据您的建议,我们在地图上只有一条固定宽度的线,随着我们捏得更多,它会因为宽度而消失。 @Kampai
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多