简体   繁体   English

在圆形叠加中绘制文本

[英]Draw text in circle overlay

I'm trying to draw some circle overlays containing text on MKMapView.我正在尝试在 MKMapView 上绘制一些包含文本的圆形叠加层。 I have subclassed the MKCircleView, in which I put the following (based on this ), but the text does not appear.我对 MKCircleView 进行了子类化,我在其中放置了以下内容(基于this ),但没有出现文本。 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.谢谢。

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: 使用MKRoadWidthAtZoomScale函数基于zoomScale缩放字体大小:

[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. 请注意,使用drawInRect将导致文本被限制在圆圈内并可能被截断。 If you want to always show all the text, you could use drawAtPoint instead. 如果要始终显示所有文本,则可以使用drawAtPoint

Combining the answers here and updating for IOS7: 结合此处的答案并更新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();
}

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. 我要做的第一件事是尝试将值打印为%f而不是%lf,因为这些值看起来很疯狂。 You should also print out the .size.width and .size.height for the two rects ( mapRect and overallCGRect ). 你还应该打印出.size.width.size.height为两个矩形( mapRectoverallCGRect )。

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. 如果这不能引导您进行合理的矩形定义,那么尝试自己定义CGRect,如CGRectMake(0,0,100,20)并查看文本是否绘制。

You can also try simply drawing a filled rectangle to the same overallCGRect that you are drawing your text into. 您还可以尝试简单地将填充的矩形绘制到您正在绘制文本的相同的overallCGRect中。

Here is a Swift version for macOS - makes use of a custom MKOverlay and MKOverlayRenderer这是适用于 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()
            
        }
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM