Core Graphics Outline Chart
I am drawing an arbitrary line with Core Graphics 4 pixels wide, now I would like this line to have a 1 pixel outline of a different color. I don't see any CG features that achieve this out of the box, but I'm looking for suggestions on how to do it. This is my existing code:
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetLineWidth(context, 4.0);
CGPoint curPoint = [(NSValue*)[points objectAtIndex:0] CGPointValue];
CGContextMoveToPoint(context, curPoint.x, curPoint.y);
for( int i = 1; i < [points count]; i++ ) {
curPoint = [(NSValue*)[points objectAtIndex:i] CGPointValue];
CGContextAddLineToPoint(context, curPoint.x, curPoint.y);
CGContextStrokePath(context);
CGContextMoveToPoint(context, curPoint.x, curPoint.y);
}
This produces a single line. I would like to create a 4px line with a 1px line highlighting the 4px line like this:
source to share
iOS 5.0 has added a new feature CGPathCreateCopyByStrokingPath()
that does what you want.
Create CGPathRef
for the black path first and then create it with CGPathCreateCopyByStrokingPath()
.
This will give you a new path that you can fill with black and stroke with red to get what you want.
Also, path creation is a bit slower. You must avoid creating paths while running the screen drawing. All of your paths must be saved in RAM and ready to go before you start drawing on the screen. drawRect:
should only draw the path, not create it.
source to share
Similar to what Abhi Beckert suggests, but you can use this function:
CGContextReplacePathWithStrokedPath(CGContextRef c);
which is also present in old SDKs - iOS 4.1, macOS X 10.6.
It's also better to create the entire path and then stroke it (or stroke and fill at the same time) at the end - in other words, you don't need to have a CGContextStrokePath inside the loop.
source to share
There is no built-in way to convert a stroke to a path and then stroke that path. However, you can get close to this by drawing the line twice: once in 6px increments (4px + 1 on each side) and then again in 4px increments in a different color
Similarly:
CGContextRef context = UIGraphicsGetCurrentContext();
CGPoint curPoint = [(NSValue*)[points objectAtIndex:0] CGPointValue];
CGContextMoveToPoint(context, curPoint.x, curPoint.y);
for( int i = 1; i < [points count]; i++ ) {
curPoint = [(NSValue*)[points objectAtIndex:i] CGPointValue];
CGContextAddLineToPoint(context, curPoint.x, curPoint.y);
}
// Set your 1 pixel highlight color here using CGContextSetRGBStrokeColor or equivalent
// CGContextSetRGBStrokeColor(...)
CGContextSetLineWidth(context, 6.0);
CGContextStrokePath(context);
// Set your 4 pixel stroke color here using CGContextSetRGBStrokeColor or equivalent
// CGContextSetRGBStrokeColor(...)
CGContextSetLineWidth(context, 4.0);
CGContextStrokePath(context);
Another idea would be to create a shadow via CGContextSetShadowWithColor (context, CGSizeZero, 1.0, yourHighlightColorHere) before drawing the stroke, although this will not draw the highlight color at full opacity. (I also can't remember if the shadows were shadow strokes - I only used them with fill)source to share