drawing a shape in drawRect - iphone

I have the following code:
- (void)drawRect:(CGRect)rect
{
CGContextRef context = UIGraphicsGetCurrentContext();
CGFloat commentHeight = 0;
CGSize commentSize = [self.highlightItem_.comment sizeWithFont:[UIFont fontWithName:kProximaNova size:18] constrainedToSize:CGSizeMake(rect.size.width, CGFLOAT_MAX) lineBreakMode:NSLineBreakByWordWrapping];
commentHeight = commentSize.height + 50;
CGContextSetRGBStrokeColor(context, 68/255.f, 68/255.f, 68/255.f, 1.0);
CGContextSetRGBFillColor(context, 68/255.f, 68/255.f, 68/255.f, 1.0);
CGContextSetLineJoin(context, kCGLineCapSquare);
CGContextSetLineWidth(context, 1.0);
CGMutablePathRef pathRef = CGPathCreateMutable();
CGPathMoveToPoint(pathRef, NULL, 0, rect.size.height - commentHeight);
CGPathAddLineToPoint(pathRef, NULL, 20, rect.size.height - commentHeight);
CGPathAddLineToPoint(pathRef, NULL, 25, rect.size.height - commentHeight - 10);
CGPathAddLineToPoint(pathRef, NULL, 30, rect.size.height - commentHeight);
CGPathAddLineToPoint(pathRef, NULL, rect.size.width, rect.size.height - commentHeight);
CGPathAddLineToPoint(pathRef, NULL, rect.size.width, rect.size.height);
CGPathAddLineToPoint(pathRef, NULL, 0, rect.size.height);
CGPathCloseSubpath(pathRef);
CGContextAddPath(context, pathRef);
//CGContextFillPath(context);
CGContextDrawPath(context, kCGPathFill);
CGPathRelease(pathRef);
}
For some reason it's not drawing the shape I want. In fact it draws nothing. Is there anything I am doing wrong?

The code above works just fine.
I guess you're drawing out of screen as I see the comment bubble on the very bottom of the iPhone 5 screen when using a full screen view.
Look below for the result when using a small centred view.

Related

How to set UILabel non rectangular frame

Im trying to make a UILabel with the edges looking like the following image.
Here is the drawRect: from my UILabel subclass.
-(void)drawRect:(CGRect)rect{
[super drawRect:rect];
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSaveGState(context);
CGRect labelRect = self.bounds;
CGPoint bottomPoint = CGPointMake(labelRect.size.width, rect.size.height);
CGPoint topMinus30Point =CGPointMake(labelRect.size.width-30, 0);
CGPoint topPoint = CGPointMake(labelRect.size.width, 0);
CGContextBeginPath (context);
//from bottom to -30 top
CGContextMoveToPoint(context, bottomPoint.x,bottomPoint.y);
CGContextAddLineToPoint(context, topMinus30Point.x,topMinus30Point.y);
//from -30 to top
CGContextMoveToPoint(context, topMinus30Point.x,topMinus30Point.y);
CGContextAddLineToPoint(context, topPoint.x,topPoint.y);
//from top to bottom
CGContextMoveToPoint(context, topPoint.x,topPoint.y);
CGContextAddLineToPoint(context, bottomPoint.x,bottomPoint.y);
CGContextClosePath(context);
CGContextStrokePath(context);
CGContextRestoreGState(context);
}
How do I crop the created path from the current frame ?
[Im just getting started with Core Graphics, so please be gentle :)]
Any pointers on how to achieve this would be really helpful.
Thanks
Try this:
- (void)drawRect:(CGRect)rect
{
CGContextRef context = UIGraphicsGetCurrentContext();
// clear drawing rect
CGContextClearRect(context, rect);
// save 1
CGContextSaveGState(context);
CGRect labelRect = self.bounds;
CGPoint bottomPoint = CGPointMake(labelRect.size.width, rect.size.height);
CGPoint topMinus30Point = CGPointMake(labelRect.size.width-30, 0);
CGPoint topPoint = CGPointMake(labelRect.size.width, 0);
CGContextBeginPath(context);
CGContextMoveToPoint(context, 0.0f, 0.0f);
CGContextAddLineToPoint(context, topMinus30Point.x, topMinus30Point.y);
CGContextAddLineToPoint(context, bottomPoint.x, bottomPoint.y);
CGContextAddLineToPoint(context, 0.0f, bottomPoint.y);
CGContextAddLineToPoint(context, 0.0f, 0.0f);
CGContextClosePath(context);
CGContextSetFillColorWithColor(context, [UIColor redColor].CGColor);
CGContextDrawPath(context, kCGPathFill);
// restore 1
CGContextRestoreGState(context);
}
Put this in the init you use:
[self setBackgroundColor:[UIColor clearColor]];
One approach is,
set the background color of label to clear color, and draw the required shape inside your drawRect method using CGContext.
Your drawRect will become like this
- (void)drawRect:(CGRect)rect{
[super drawRect:rect];
CGContextRef context = UIGraphicsGetCurrentContext();
CGRect labelRect = self.bounds;
CGPoint bottomPoint = CGPointMake(labelRect.size.width, rect.size.height);
CGPoint topMinus30Point =CGPointMake(labelRect.size.width-30, 0);
//from bottom to -30 top
CGContextMoveToPoint(context, self.bounds.origin.x,self.bounds.origin.y);
CGContextAddLineToPoint(context, topMinus30Point.x,topMinus30Point.y);
CGContextAddLineToPoint(context, bottomPoint.x,bottomPoint.y);
CGContextAddLineToPoint(context, self.bounds.origin.x,self.bounds.origin.x + self.bounds.size.height);
CGContextAddLineToPoint(context, self.bounds.origin.x,self.bounds.origin.y);
CGContextSetFillColorWithColor(context, [UIColor greenColor].CGColor);
CGContextFillPath(context);
}
Another approach is using the CGContextClip using this approach your drawRect will become like this
CGContextMoveToPoint(context, self.bounds.origin.x,self.bounds.origin.y);
CGContextAddLineToPoint(context, topMinus30Point.x,topMinus30Point.y);
CGContextAddLineToPoint(context, bottomPoint.x,bottomPoint.y);
CGContextAddLineToPoint(context, self.bounds.origin.x,self.bounds.origin.x + self.bounds.size.height);
CGContextAddLineToPoint(context, self.bounds.origin.x,self.bounds.origin.y);
CGContextClip(context);
CGContextSetFillColorWithColor(context, [UIColor greenColor].CGColor);
CGContextFillRect(context, self.bounds);
Hope this helps

adding border color and rounded corner to CGMutableRefPath

I have the following code on my drawRect:
CGMutablePathRef pathRef = CGPathCreateMutable();
CGPathMoveToPoint(pathRef, NULL, 0, 220);
CGPathAddLineToPoint(pathRef, NULL, rect.size.width, 220);
CGPathAddLineToPoint(pathRef, NULL, rect.size.width, rect.size.height);
CGPathAddLineToPoint(pathRef, NULL, 0, rect.size.height);
CGPathCloseSubpath(pathRef);
how do I add a black border to this?
Make sure you have a context:
CGContextRef context = UIGraphicsGetCurrentContext();
and then:
aColor = [UIColor blackColor];
[aColor setStroke];
CGContextSetLineWidth(context, 2.0f);
CGContextAddPath(context, pathRef);
CGContextStrokePath(context);

CoreGraphics same code draw different

I write a msg background in tableviewcell, but when scrolling, the view become different. seems like the "context" store some state.
The code draw a round rect with a arrow.The arrow size should be fixed,but in fact it will change sometimes then scrolling.
- (void)drawRect:(CGRect)rect
{
// Drawing code
CGContextRef context = UIGraphicsGetCurrentContext();
CGFloat width = self.frame.size.width;
CGFloat height = self.frame.size.height;
CGFloat arrowHeight = 10;
CGFloat arrowWidth = 5;
CGFloat arrowOffset = 5;
CGFloat radius = 5;
CGFloat shadowHeight = 2;
CGFloat shadowOffset = 4;
CGColorRef shadowColor = [UIColor colorWithRed:0.2f
green:0.2f
blue:0.2f
alpha:0.5f].CGColor;
CGColorRef color;
color = [UIColor whiteColor].CGColor;
CGContextSaveGState(context);
CGContextMoveToPoint(context, width/2, 0);
CGContextAddArcToPoint(context, width - arrowWidth, 0, width - arrowWidth, height - shadowOffset, radius);
CGContextAddLineToPoint(context, width - arrowWidth, arrowOffset);
CGContextAddLineToPoint(context, width, arrowOffset + arrowHeight/2);
CGContextAddLineToPoint(context, width - arrowWidth, arrowOffset + arrowHeight);
CGContextAddArcToPoint(context, width - arrowWidth, height - shadowOffset, shadowOffset, height - shadowOffset, radius);
CGContextAddArcToPoint(context, shadowOffset, height - shadowOffset, shadowOffset, 0, radius);
CGContextAddArcToPoint(context, shadowOffset, 0, width, 0, radius);
CGContextSetShadowWithColor(context, CGSizeMake(0, shadowHeight), 3.0, shadowColor);
CGContextSetFillColorWithColor(context, color);
CGContextFillPath(context);
CGContextRestoreGState(context);
}
the effect like this:
I find the problem. the view should redraw when cell is reused,or the view will use the view in last cell to show.
so, just call [theView setNeedsDisplay] to let the view call drawRect again.

Why is my CoreGraphics shape not showing a border?

This is the code I have:
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextClearRect(context, rect);
CGContextSetFillColorWithColor(context, [BUTTON_COLOR CGColor]);
CGContextSetStrokeColorWithColor(context, [[UIColor blackColor] CGColor]);
CGContextSetLineWidth(context, 1);
int radius = CORNER_RADIUS;
CGContextMoveToPoint(context, 0, self.frame.size.height / 2);
CGContextAddLineToPoint(context, POINT_WIDTH, self.frame.size.height);
CGContextAddLineToPoint(context, rect.origin.x + rect.size.width - radius,
rect.origin.y + rect.size.height);
CGContextAddArc(context, rect.origin.x + rect.size.width - radius,
rect.origin.y + rect.size.height - radius, radius, M_PI / 2, 0.0f, 1);
CGContextAddLineToPoint(context, rect.origin.x + rect.size.width, rect.origin.y + radius);
CGContextAddArc(context, rect.origin.x + rect.size.width - radius, rect.origin.y + radius,
radius, 0.0f, -M_PI / 2, 1);
CGContextAddLineToPoint(context, POINT_WIDTH, 0);
CGContextAddLineToPoint(context, 0, self.frame.size.height / 2);
CGContextClosePath(context);
CGContextDrawPath(context, kCGPathFillStroke);
Why is it not drawing a border around the shape?
EDIT: Now it draws the shape, thanks to changing the last line, but it draws an extra line around it, like this:
http://cl.ly/0u0e051a060m161u0n08
Use CGContextDrawPath(context, kCGPathFillStroke) instead of CGContextFillPath() and CGContextStrokePath().
The thing is, after the first call to CGContextFillPath() or CGContextStrokePath() the context's path is cleared, so the second call does not have a path to work with.

Simple drawing with Quartz - Core Graphics

I want to draw a rectangle with the top-left corner rounded with 3 sub-spaces in it. Something like this:
_______
|_|_____|
| |
|_______|
But for some reason I cannot get the inner two lines drawn.
- (void) drawRect:(CGRect)rect{
CGContextRef context = UIGraphicsGetCurrentContext();
float cornerRadius = 25.0;
float w = self.bounds.size.width;
float h = self.bounds.size.height;
CGContextMoveToPoint(context, cornerRadius, 0);
CGContextAddQuadCurveToPoint(context, 0, 0, 0, cornerRadius);
CGContextAddLineToPoint(context, 0, h);
CGContextAddLineToPoint(context, w, h);
CGContextAddLineToPoint(context, w, 0);
CGContextAddLineToPoint(context, cornerRadius, 0);
//drawing settings
CGContextSetLineWidth(context, 0.5);
CGContextSetStrokeColorWithColor(context, [UIColor blackColor].CGColor);
CGContextSetFillColorWithColor(context, [UIColor white].CGColor);
//draw rectangle
CGContextDrawPath(context, kCGPathFillStroke);
//draw title/label partition
CGContextMoveToPoint(context, TITLE_HEIGHT, 0);
CGContextAddLineToPoint(context, TITLE_HEIGHT, TITLE_HEIGHT);
CGContextStrokePath(context);
//draw title/content partition
CGContextMoveToPoint(context, 0, TITLE_HEIGHT);
CGContextAddLineToPoint(context, self.bounds.size.width, TITLE_HEIGHT);
CGContextStrokePath(context);
}
I wonder what am I mistaking here... ;(
Thanks in advance
Try to comment out the CGContextSetFillColorWithColor line for a while - maybe the rectangle is overlapping those lines?