How to draw a text in MKCircleview? i have to print a text on the overlay of MKMapview. is it possible?
Within this section of my overlay view subclass of MKOverlayView:
- (void)drawMapRect:(MKMapRect)mapRect
zoomScale:(MKZoomScale)zoomScale
inContext:(CGContextRef)context
You should do /something/ like this:
CGContextSetTextMatrix(context, CGAffineTransformMake(1.0, 0.0, 0.0, -1.0, 0.0, 0.0));
// Setup text rendering stuff.
CGFloat fontHeight = rect.size.height/2.0f;
CGContextSelectFont(context, "Thonburi", fontHeight, kCGEncodingMacRoman);
CGContextSetRGBFillColor(context, 0, 0, 0, 1);
CGContextSetRGBStrokeColor(context, 0, 0, 0, 1);
// Set string.
const char *text = [[NSString stringWithFormat:#"%d",clusters[i].count] UTF8String];
int len = strlen(text);
// Render text invisible.
CGContextSetTextDrawingMode(context, kCGTextInvisible);
CGContextShowTextAtPoint(context,
0,
0,
text,
strlen(text));
// Get actual point it was renderered.
CGPoint pt = CGContextGetTextPosition(context);
// Set text to visible.
CGContextSetTextDrawingMode(context, kCGTextFillStroke);
// Actually render text.
CGContextShowTextAtPoint(context,
rect.origin.x + (0.5f * rect.size.width) - (0.5f * pt.x), // Origin + half the width - half the width of text == center aligned text?
rect.origin.y + (1.25f * fontHeight), // Hack. 1 1/4 font height (which is half rect height) == center vert. aligned text.
text,
len);
This will render the text centered in the middle of the circle.
A few warnings about the above code... it's actually taken from a subclass of MKOverlayPathView within which I draw many many circles on the overlay view in different locations and thus needed a fairly dynamic method of drawing the text in the right place. Thus the code will probably not be a drop in solution for you and a bit more complicated than you actually need. However it should point you in the right direction.
Please bear in mind that having more than a couple of overlay views on a mapkit is a path to insanity with random crashes and stack traces as the layers consume more and more ram. Thus if you have more than a small handful of overlays I would recommend you also go down the MKOverlayPathView route.
I banged my head on the desk for almost a month before I discovered why it was crashing so much at random times.
My code is for clustering, placing text in the middle of each circle with the number of items in that cluster.
Related
I am trying to draw a box/path in drawRect in one of my view's, the path rect is:
CGRect pathRect = CGRectMake(self.buttonSize_ + 25, commentYOffset, rect.size.width - 80, 40);
and before this I have:
CGContextSetTextMatrix(context, CGAffineTransformIdentity);
CGContextTranslateCTM(context, 0.0, rect.size.height);
CGContextScaleCTM(context, 1.0, -1.0);
I wanted this path to be drawn 100 pixels from the top, so what I did is set that commentYOffset to 100, however this doesn't do it. What am I doing wrong so that when I draw this path it starts at 100 pixels from the top?
CGContextTranslateCTM(context,…) applies a translation transform to context. The translation is applied after any existing transform in the drawing context. Those last two lines in the code you posted effectively flip the vertical on your drawing context. Just leave them out and the path will be drawn where you want.
Edit: adit says he needs the transforms to keep some text drawing right side up, so: If you need to flip the vertical on your drawing context (as you're doing) then just remember that after applying these transformations zero-y is at the bottom of rect and the positive y-axis points towards the top of rect. So to draw your path 100 pixels from the top you should make
commentYOffset = CGRectGetMaxY(rect) - 40.0 - 100.0;
and that 40 is because your rect is 40 points tall. Actually it's better practice to make these named constants so you don't have to copy magic numbers all over the place going forward. Then your code will look something like this:
commentYOffset = CGRectGetMaxY(rect) - kPathRectHeight - kPathTopMargin;
I'm drawing several circles within my view by means of the drawRect function.
I'd like to have my circles pop up (scale to 1.2 -> scale to 1.0)
I've used coreanimation in the past but using OpenGL takes different functions.
Here's a snippit of my code which draws a circle in my view:
//calling draw function
CGContextRef contextRef = UIGraphicsGetCurrentContext();
//setting a specific fill color
CGContextSetRGBFillColor(contextRef, 0.0, 255.0, 0.0, 1.0);
//drawing the circle with a specific height, weight and x,y location
CGContextFillEllipseInRect(contextRef, CGRectMake(30 ,30, 20,20));
How can I animate this circle that it 'pops up'.
"Pops up" is not telling me that much.
if you want it to go from small to big modify width and height of rect.use a global int variable
I'm using a series of CGContext commands to create text to be used for generating a pdf file:
CGContextSelectFont (pdfContext, "Helvetica", 14, kCGEncodingMacRoman);
CGContextSetTextDrawingMode (pdfContext, kCGTextFill);
CGContextSetRGBFillColor (pdfContext, 0, 0, 0, 1);
CGContextSetTextMatrix(pdfContext, CGAffineTransformMake(1.0,0.0, 0.0, -1.0, 0.0, 0.0));
I would like to right justify the text though. Any idea on how to do this? For example, is there a method that allows you to specify the origin as the top right corner of the text, not the top left?
CGContextShowTextAtPoint (pdfContext, x, y, text, strlen(text));
Thanks!
Right and center justifications are not supported. In order to draw right aligned text, you need to compute the text width, subtract the text width from the right aligned x and then draw the text at the computed position.
I'm trying to add a little red line on the bottom of my UIView.
I want the line to be a 1px line.
Can someone tell me why the following code:
- (void)drawRect:(CGRect)rect {
CGContextRef currentContext = UIGraphicsGetCurrentContext();
CGContextSaveGState(currentContext);
CGContextSetRGBFillColor(currentContext, 0.0f, 0.0f, 0.0f, 1.0f);
CGContextFillRect(currentContext, RECT(0, 0, rect.size.width, rect.size.height - 8));
CGContextSetLineWidth(currentContext, 1);
CGContextSetRGBStrokeColor(currentContext, 1.0f, 0.0f, 0.0f, 1.0f);
CGContextBeginPath(currentContext);
CGContextMoveToPoint(currentContext, 0, rect.size.height - 7);
CGContextAddLineToPoint(currentContext, rect.size.width, rect.size.height - 7);
CGContextStrokePath(currentContext);
CGContextRestoreGState(currentContext);
}
Draws a line that spans 2px in height?
The integral coordinates indicate places half-way between pixels; that is, (0,0) is in the upper-left corner, above and to the left of the upper-left pixel; similarly, (1,0) is between the first and second pixels; finally, (0.5,0.5) is at the center of the upper-left pixel.
According to the documentation for CGContextSetLineWidth, "when stroked, the line straddles the path, with half of the total width on either side." Thus, if the path is lying precisely in between the pixels, the line will be stroked half on one row of pixels, half on the other.
Hence, to get a sharp pixel line, you must offset your coordinates by half a pixel: for your x coordinate, use rect.size.height - 7.5 instead of - 7.
By the way, when drawing rectangles, it is handy to use CGRectInset(rect, 0.5, 0.5) to achieve this.
Do you use an iPhone 4? The iPhone 4 uses a coordinate system with a scale factor of 2. So you would need to set the line width to 0.5 in order to get what you want.
(The coordinate system is set up that way so the same code produces the same output on all models.)
Lines are by default drawn antialiased (unless you configure otherwise). Thus any line that's not strictly vertical or horizontal and starting and ending on a pixel will likely partially cover multiple pixels in some rows and/or columns, making it look like a wider grey line instead of a thin higher-contrast line.
I am attempting to fill some text with a gradient-fill, where by I set the text drawing mode to clipping, and then paint a gradient-fill.
The problem is, whenever I set the text drawing mode to clip, every character of the text string is placed on top of each other, rather than being painted in a sequence to form a word - it is most bizarre!
My code looks like this:
CGRect r = CGRectInset(self.frame, 55, 8);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSaveGState(context);
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGFloat components[8] = {44/255, 54/255, 66/255, 1.0
,75/255, 92/255, 111/255, 1.0};
CGFloat locations[2] = {0, 1};
// draw the text's gradient fill
CGGradientRef gradient = CGGradientCreateWithColorComponents(colorSpace, components, locations, 2);
CGContextSetTextDrawingMode(context, kCGTextClip);
[monthString drawInRect:r withFont:f lineBreakMode:UILineBreakModeWordWrap alignment:UITextAlignmentCenter];
CGContextFillRect(context, CGRectMake(0, 0, 320, 20));
It appears that the UIKit NSString additions that let you do drawInRect:withFont: and the like don't play well with the kCGTextClip drawing mode. I've seen the same behavior, and in this answer I provide code to fill text with a gradient using pure Quartz drawing calls. The downside to this approach is that you are limited to the MacRoman text encoding, which lacks support for many Unicode symbols.