5

我有一个继承自 MKOverlayPathView 的地图自定义视图。我需要这个自定义视图来显示圆圈、线条和文本。

我已经设法使用路径绘图 CGPathAddArc 和 CGPathAddLineToPoint 函数绘制圆和线。

但是,我仍然需要添加文本。

我尝试使用添加文本

 [text drawAtPoint:centerPoint withFont:font];

但我得到了无效的上下文错误。

任何的想法?

4

2 回答 2

8

使用MKOverlayPathView,我认为添加文本的最简单方法是覆盖drawMapRect:zoomScale:inContext:并将路径和文本绘图放在那里(并且什么都不做或不实现createPath)。

但是,如果您仍然要使用drawMapRect,您可能只想切换到子类化普通MKOverlayView而不是MKOverlayPathView.

使用MKOverlayView, 覆盖该方法并使用(or or )drawMapRect:zoomScale:inContext:绘制圆。 CGContextAddArcCGContextAddEllipseInRectCGPathAddArc

您可以使用此方法绘制文本drawAtPoint,该方法将具有所需的context.

例如:

-(void)drawMapRect:(MKMapRect)mapRect zoomScale:(MKZoomScale)zoomScale inContext:(CGContextRef)context
{
    //calculate CG values from circle coordinate and radius...
    CLLocationCoordinate2D center = circle_overlay_center_coordinate_here;

    CGPoint centerPoint = 
        [self pointForMapPoint:MKMapPointForCoordinate(center)];

    CGFloat radius = MKMapPointsPerMeterAtLatitude(center.latitude) * 
                         circle_overlay_radius_here;

    CGFloat roadWidth = MKRoadWidthAtZoomScale(zoomScale);

    //draw the circle...
    CGContextSetStrokeColorWithColor(context, [UIColor blueColor].CGColor);
    CGContextSetFillColorWithColor(context, [[UIColor blueColor] colorWithAlphaComponent:0.2].CGColor);
    CGContextSetLineWidth(context, roadWidth);
    CGContextAddArc(context, centerPoint.x, centerPoint.y, radius, 0, 2 * M_PI, true);
    CGContextDrawPath(context, kCGPathFillStroke);

    //draw the text...
    NSString *text = @"Hello";
    UIGraphicsPushContext(context);
    [[UIColor redColor] set];
    [text drawAtPoint:centerPoint 
             withFont:[UIFont systemFontOfSize:(5.0 * roadWidth)]];
    UIGraphicsPopContext();
}

关于另一个答案中的评论......

当相关联的中心坐标或半径(或其他)MKOverlay发生变化时,您可以MKOverlayView通过调用它来进行“移动” setNeedsDisplayInMapRect:(而不是再次删除和添加覆盖)。(使用 aMKOverlayPathView时,您可以invalidatePath改为调用。)

调用时setNeedsDisplayInMapRect:,可以boundingMapRect为 map rect 参数传递叠加层的 。

在 WWDC 2010 的 LocationReminders 示例应用程序中,覆盖视图使用 KVO 来观察关联MKOverlay的更改,并在检测到圆圈属性发生更改时自行移动,但您可以通过其他方式监视更改并setNeedsDisplayInMapRect:从覆盖视图外部显式调用.

(在对另一个答案的评论中,我确实提到了使用MKOverlayPathView,这就是 LocationReminders 应用程序实现移动圆圈覆盖视图的方式。但我应该提到你也可以MKOverlayView用来画一个圆圈。对此感到抱歉。)

于 2012-05-10T21:06:04.543 回答
1

推送上下文UIGraphicsPushContext给我带来了一个问题。提醒一下,该方法drawMapRect:zoomScale:inContext:是同时从不同的线程调用的,所以我必须从调用的地方开始同步这段UIGraphicsPushContext代码UIGraphicsPopContext

此外,在计算字体大小时,[UIFont systemFontOfSize:(5.0 * roadWidth)]应考虑[UIScreen mainScreen].scale,对于 iPad、iPad2、iPhone31和 iPhone4-5 和 iPad3 是2。否则,文本大小会从 iPad2 到 iPad3 不同。

所以对我来说,结局是这样的:[UIFont boldSystemFontOfSize:(6.0f * [UIScreen mainScreen].scale * roadWidth)]

于 2012-11-19T07:44:30.530 回答