【问题标题】:Is there a way to add text using Paths Drawing有没有办法使用路径绘图添加文本
【发布时间】:2012-05-10 07:22:46
【问题描述】:

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

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

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

我尝试使用

添加文本
 [text drawAtPoint:centerPoint withFont:font];

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

有什么想法吗?

【问题讨论】:

    标签: ios mkmapview mkoverlay


    【解决方案1】:

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

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

    使用MKOverlayView,覆盖drawMapRect:zoomScale:inContext: 方法并使用CGContextAddArc(或CGContextAddEllipseInRectCGPathAddArc)绘制圆。

    您可以在此方法中使用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 的中心坐标或半径(或其他)发生变化时,您可以通过在其上调用setNeedsDisplayInMapRect: 来使MKOverlayView“移动”(而不是再次删除和添加覆盖)。 (使用MKOverlayPathView 时,您可以调用invalidatePath。)

    调用setNeedsDisplayInMapRect:时,可以将覆盖层的boundingMapRect传递给map rect参数。

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

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

    【讨论】:

    • 谢谢 Anna...我用 MKOverlayPathView 画了一个圆圈,效果很好。除了我需要动画视图运动。因为目前地图上的默认用户标记会在位置更改时以动画方式移动。因此,我的圆形视图也应该是动画的。我知道我需要使用 [UIView beginAnimations 和 [UIView commitAnimations];但我不知道把这段代码放在哪里。例如,我是否需要在 MKOverlayPathView 中的 invalidatePath 之前和之后放置它?
    • 通常是的,要为视图设置动画,您将使用 beginAnimations/commitAnimations(或基于块的 animateWithDuration),但这似乎不适用于 MKOverlayViews(至少我不知道如何)。但是,如果您不介意使用 MKAnnotation(带有圆形图像或圆形绘图)而不是 MKOverlay,则可以平滑地为注释视图设置动画。例如,请参阅stackoverflow.com/questions/8564013/…。注释的唯一问题是图像/绘图将保持恒定大小(如用户位置蓝点)。
    【解决方案2】:

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

    在计算[UIFont systemFontOfSize:(5.0 * roadWidth)] 中的字体大小时,还应考虑[UIScreen mainScreen].scale,对于iPad、iPad2、iPhone3 为1,对于iPhone4-5 和iPad3 为2。否则,iPad2 到 iPad3 的文字大小会有所不同。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-03-30
      • 1970-01-01
      • 1970-01-01
      • 2013-10-16
      • 2021-01-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多