在圆形叠加层中绘制文本

发布于 2024-12-11 08:44:41 字数 1200 浏览 1 评论 0原文

我正在尝试在 MKMapView 上绘制一些包含文本的圆形叠加层。 我对 MKCircleView 进行了子类化,在其中放置了以下内容(基于 this ),但文本不出现。圆圈正确显示。 (也尝试了第一个响应的解决方案,结果相同)。

-(void)drawMapRect:(MKMapRect)mapRect zoomScale:(MKZoomScale)zoomScale inContext:(CGContextRef)context {
   [super drawMapRect:mapRect zoomScale:zoomScale inContext:context];
   NSString * t= @"XXXXX\nXXXX" ;
   UIGraphicsPushContext(context);
   CGContextSaveGState(context); 
   [[UIColor redColor] set];
   CGRect overallCGRect = [self rectForMapRect:[self.overlay boundingMapRect]];
   NSLog(@"MKC :  %lf, %lf ----> %lf , %lf ", mapRect.origin.x ,mapRect.origin.y , overallCGRect.origin.x, overallCGRect.origin.y);
   [t drawInRect:overallCGRect withFont:[UIFont fontWithName:@"Arial" size:10.0] lineBreakMode:UILineBreakModeClip alignment:UITextAlignmentCenter];
   CGContextRestoreGState(context);
   UIGraphicsPopContext();
}

调试时,我得到这样的值

MKC :  43253760.000000, 104071168.000000 ----> 1.776503 , 1.999245 
MKC :  43253760.000000, 104071168.000000 ----> -1.562442 , -2.043090

它们正常吗?我缺少什么?

谢谢。

I'm trying to draw some circle overlays containing text on MKMapView.
I have subclassed the MKCircleView, in which I put the following (based on this), but the text does not appear. The circles show up correctly. (Also tried the first response's solution, same result).

-(void)drawMapRect:(MKMapRect)mapRect zoomScale:(MKZoomScale)zoomScale inContext:(CGContextRef)context {
   [super drawMapRect:mapRect zoomScale:zoomScale inContext:context];
   NSString * t= @"XXXXX\nXXXX" ;
   UIGraphicsPushContext(context);
   CGContextSaveGState(context); 
   [[UIColor redColor] set];
   CGRect overallCGRect = [self rectForMapRect:[self.overlay boundingMapRect]];
   NSLog(@"MKC :  %lf, %lf ----> %lf , %lf ", mapRect.origin.x ,mapRect.origin.y , overallCGRect.origin.x, overallCGRect.origin.y);
   [t drawInRect:overallCGRect withFont:[UIFont fontWithName:@"Arial" size:10.0] lineBreakMode:UILineBreakModeClip alignment:UITextAlignmentCenter];
   CGContextRestoreGState(context);
   UIGraphicsPopContext();
}

When debugging, I get values like these

MKC :  43253760.000000, 104071168.000000 ----> 1.776503 , 1.999245 
MKC :  43253760.000000, 104071168.000000 ----> -1.562442 , -2.043090

Are they normal ? What am I missing ?

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

吃颗糖壮壮胆 2024-12-18 08:44:41

我相信您的代码正在工作,问题是文本没有正确缩放,使其不可见。

使用 MKRoadWidthAtZoomScale 函数根据 zoomScale 缩放字体大小:

[t drawInRect:overallCGRect withFont:[UIFont fontWithName:@"Arial" 
    size:(10.0 * MKRoadWidthAtZoomScale(zoomScale))] 
    lineBreakMode:UILineBreakModeClip alignment:UITextAlignmentCenter];

另请确保使用与底层圆圈颜色不同的文本颜色。

请注意,使用drawInRect将导致文本被限制在圆圈内,并且可能会被截断。如果您想始终显示所有文本,可以使用drawAtPoint代替。

I believe your code is working and the problem is that the text is not being scaled properly making it invisible.

Scale the font size based on the zoomScale using the MKRoadWidthAtZoomScale function:

[t drawInRect:overallCGRect withFont:[UIFont fontWithName:@"Arial" 
    size:(10.0 * MKRoadWidthAtZoomScale(zoomScale))] 
    lineBreakMode:UILineBreakModeClip alignment:UITextAlignmentCenter];

Also be sure to use a text color that's different from the underlying circle's color.

Note that using drawInRect will result in the text being restricted to inside the circle and may get truncated. If you want to always show all the text, you could use drawAtPoint instead.

把昨日还给我 2024-12-18 08:44:41

结合这里的答案并更新 IOS7:

-(void)drawMapRect:(MKMapRect)mapRect zoomScale:(MKZoomScale)zoomScale inContext:(CGContextRef)context
{
    [super drawMapRect:mapRect zoomScale:zoomScale inContext:context];

    UIGraphicsPushContext(context);
    CGContextSaveGState(context);
    [[UIColor blueColor] set];

    NSDictionary *fontAttributes = @{NSFontAttributeName:[UIFont systemFontOfSize:10.0f * MKRoadWidthAtZoomScale(zoomScale)]};
    CGSize size = [[[self overlay] title] sizeWithAttributes:fontAttributes];
    CGFloat height = ceilf(size.height);
    CGFloat width  = ceilf(size.width);

    CGRect circleRect = [self rectForMapRect:[self.overlay boundingMapRect]];
    CGPoint center = CGPointMake(circleRect.origin.x + circleRect.size.width /2, circleRect.origin.y + circleRect.size.height /2);
    CGPoint textstart = CGPointMake(center.x - width/2, center.y - height /2 );

    [[[self overlay] title] drawAtPoint:textstart withAttributes:fontAttributes];

    CGContextRestoreGState(context);
    UIGraphicsPopContext();
}

Combining the answers here and updating for IOS7:

-(void)drawMapRect:(MKMapRect)mapRect zoomScale:(MKZoomScale)zoomScale inContext:(CGContextRef)context
{
    [super drawMapRect:mapRect zoomScale:zoomScale inContext:context];

    UIGraphicsPushContext(context);
    CGContextSaveGState(context);
    [[UIColor blueColor] set];

    NSDictionary *fontAttributes = @{NSFontAttributeName:[UIFont systemFontOfSize:10.0f * MKRoadWidthAtZoomScale(zoomScale)]};
    CGSize size = [[[self overlay] title] sizeWithAttributes:fontAttributes];
    CGFloat height = ceilf(size.height);
    CGFloat width  = ceilf(size.width);

    CGRect circleRect = [self rectForMapRect:[self.overlay boundingMapRect]];
    CGPoint center = CGPointMake(circleRect.origin.x + circleRect.size.width /2, circleRect.origin.y + circleRect.size.height /2);
    CGPoint textstart = CGPointMake(center.x - width/2, center.y - height /2 );

    [[[self overlay] title] drawAtPoint:textstart withAttributes:fontAttributes];

    CGContextRestoreGState(context);
    UIGraphicsPopContext();
}
生活了然无味 2024-12-18 08:44:41

您的文本很可能被绘制到不可见的矩形中。

我要做的第一件事是尝试将值打印为 %f 而不是 %lf,因为这些值看起来很疯狂。您还应该打印出两个矩形的 .size.width.size.heightmapRectoverallCGRect >)。

如果这不能引导您进行合理的矩形定义,请尝试自己定义 CGRect,如 CGRectMake(0,0,100,20) 并查看文本是否绘制。

您还可以尝试简单地将一个填充矩形绘制到与您绘制文本的相同的 overallCGRect 上。

It is most likely that your text is drawn to a rectangle which is not visible.

First thing I would do is try printing the values as %f instead of %lf, as those values look crazy. You should also print out the .size.width and .size.height for the two rects (mapRect and overallCGRect).

If that doesn't lead you to a sensible rectangle definition, then try defining a CGRect yourself like CGRectMake(0,0,100,20) and see if the text draws.

You can also try simply drawing a filled rectangle to the same overallCGRect that you are drawing your text into.

兔小萌 2024-12-18 08:44:41

这是 macOS 的 Swift 版本 - 使用自定义 MKOverlay 和 MKOverlayRenderer

    /// Usage
    /// Labels
    ///
    /// let label1 = makeLabel([CLLocationCoordinate2DMake(lat + self.dyW / 2.0, lon - self.dxW / 2.0),
    ///                        CLLocationCoordinate2DMake(lat + self.dyW / 2.0, lon + self.dxW / 2.0)])
    /// label1.isAbove = false
    /// label1.text = "\(yIndex+1), \(xIndex+1)"
    /// overlays.append(label1)
    /// mapView?.addOverlay(label1)
    ///
    /// let label2 = makeLabel([CLLocationCoordinate2DMake(lat - self.dyW / 2.0, lon - self.dxW / 2.0),
    ///                        CLLocationCoordinate2DMake(lat - self.dyW / 2.0, lon + self.dxW / 2.0)])
    /// label2.isAbove = true
    /// label2.text = "\((lat - self.dyW / 2.0).formatted(3)), \((lon - self.dxW / 2.0).formatted(3))"
    /// overlays.append(label2)
    /// mapView?.addOverlay(label2)
    
    class Label: MKPolyline {
        
        var text: String = "TEXT"
        var isAbove: Bool = true
        
        let textColor = NSColor.white.withAlphaComponent(0.8).cgColor
        
    }
    
    // Custom TextOverlay
    class LabelRenderer: MKOverlayRenderer {
          
        override func draw(_ mapRect: MKMapRect, zoomScale: MKZoomScale, in context: CGContext) {
            
            // Draw Text in here
    
            guard let label = overlay as? Label else {
                print("Error this is not a Label overlay !!")
                return
            }
            
            let rect = rect(for: overlay.boundingMapRect)
           
            let textSize = 400.0
            let margin = 100.0
            
            
            
            // Draw a border if required
            //let yPos        = label.isAbove ? rect.origin.y - textSize : rect.origin.y
            
            //let center      = CGPoint(x: rect.origin.x, y: yPos)
            //let drawRect = CGRect(origin: center, size: CGSize(width: width, height: textSize))
            //context.setFillColor(NSColor.cyan.withAlphaComponent(0.8).cgColor)
            //context.fill(drawRect)
            
            // Save the state because we have to flip things for drawing text
            context.saveGState()
            
            let textStart   = CGPoint(x: rect.origin.x + 100, y: label.isAbove ? (rect.origin.y + margin ) : (rect.origin.y) - textSize)
           
            context.setStrokeColor(label.textColor)
            context.setFillColor(label.textColor)
            
            context.setTextDrawingMode(.fill)
            let font = NSFont.systemFont(ofSize: textSize)
            let string = NSAttributedString(string: label.text, attributes: [NSAttributedString.Key.font: font, NSAttributedString.Key.foregroundColor: label.textColor])
            
            context.textPosition = textStart
            context.scaleBy(x: 1.0, y: -1.0)
            
            let line = CTLineCreateWithAttributedString(string)
            CTLineDraw(line, context)
            
            // Restore the state just incase there is some other drawing required
            context.restoreGState()
            
        }
    }

Here is a Swift version for macOS - makes use of a custom MKOverlay and MKOverlayRenderer

    /// Usage
    /// Labels
    ///
    /// let label1 = makeLabel([CLLocationCoordinate2DMake(lat + self.dyW / 2.0, lon - self.dxW / 2.0),
    ///                        CLLocationCoordinate2DMake(lat + self.dyW / 2.0, lon + self.dxW / 2.0)])
    /// label1.isAbove = false
    /// label1.text = "\(yIndex+1), \(xIndex+1)"
    /// overlays.append(label1)
    /// mapView?.addOverlay(label1)
    ///
    /// let label2 = makeLabel([CLLocationCoordinate2DMake(lat - self.dyW / 2.0, lon - self.dxW / 2.0),
    ///                        CLLocationCoordinate2DMake(lat - self.dyW / 2.0, lon + self.dxW / 2.0)])
    /// label2.isAbove = true
    /// label2.text = "\((lat - self.dyW / 2.0).formatted(3)), \((lon - self.dxW / 2.0).formatted(3))"
    /// overlays.append(label2)
    /// mapView?.addOverlay(label2)
    
    class Label: MKPolyline {
        
        var text: String = "TEXT"
        var isAbove: Bool = true
        
        let textColor = NSColor.white.withAlphaComponent(0.8).cgColor
        
    }
    
    // Custom TextOverlay
    class LabelRenderer: MKOverlayRenderer {
          
        override func draw(_ mapRect: MKMapRect, zoomScale: MKZoomScale, in context: CGContext) {
            
            // Draw Text in here
    
            guard let label = overlay as? Label else {
                print("Error this is not a Label overlay !!")
                return
            }
            
            let rect = rect(for: overlay.boundingMapRect)
           
            let textSize = 400.0
            let margin = 100.0
            
            
            
            // Draw a border if required
            //let yPos        = label.isAbove ? rect.origin.y - textSize : rect.origin.y
            
            //let center      = CGPoint(x: rect.origin.x, y: yPos)
            //let drawRect = CGRect(origin: center, size: CGSize(width: width, height: textSize))
            //context.setFillColor(NSColor.cyan.withAlphaComponent(0.8).cgColor)
            //context.fill(drawRect)
            
            // Save the state because we have to flip things for drawing text
            context.saveGState()
            
            let textStart   = CGPoint(x: rect.origin.x + 100, y: label.isAbove ? (rect.origin.y + margin ) : (rect.origin.y) - textSize)
           
            context.setStrokeColor(label.textColor)
            context.setFillColor(label.textColor)
            
            context.setTextDrawingMode(.fill)
            let font = NSFont.systemFont(ofSize: textSize)
            let string = NSAttributedString(string: label.text, attributes: [NSAttributedString.Key.font: font, NSAttributedString.Key.foregroundColor: label.textColor])
            
            context.textPosition = textStart
            context.scaleBy(x: 1.0, y: -1.0)
            
            let line = CTLineCreateWithAttributedString(string)
            CTLineDraw(line, context)
            
            // Restore the state just incase there is some other drawing required
            context.restoreGState()
            
        }
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文