CGPath with outline

2019-06-16 21:25发布

问题:

I am trying to draw a CGPath that has a stroke for it's stroke.

Basically I want a draw a line using CGPath. I then want to go back and draw lines on both sides of the last CGPath giving it the effect that it is outlines.

This line can bend and turn in any way but I always need the two lines on the outside to follow.

EDIT: I need to be able to make the middle of the line transparent but the outlines solid black.

回答1:

Use CGPathCreateCopyByStrokingPath to create a new path by stroking your old path at some width. Then draw your new path using kCGPathFillStroke.

- (void)drawRect:(CGRect)rect {
  CGContextRef context = UIGraphicsGetCurrentContext();

  CGMutablePathRef path = CGPathCreateMutable();
  CGPathMoveToPoint(path, NULL, 50, 50);
  CGPathAddLineToPoint(path, NULL, 200, 200);

  CGPathRef thickPath = CGPathCreateCopyByStrokingPath(path, NULL, 10, kCGLineCapButt, kCGLineJoinBevel, 0);
  CGContextAddPath(context, thickPath);

  CGContextSetStrokeColorWithColor(context, [UIColor blackColor].CGColor);
  CGContextSetFillColorWithColor(context, [UIColor blueColor].CGColor);
  CGContextSetLineWidth(context, 3);
  CGContextDrawPath(context, kCGPathFillStroke);

  CGPathRelease(thickPath);
  CGPathRelease(path);
}


回答2:

The simplest solution would just be to stroke the path twice. First with black at a bigger stroke width and then stroke the same path again using the blue color with a slightly smaller stroke width.

Edit:
If I remember correctly you can use CGPathCreateCopyByStrokingPath(...) to create a new path that you then can both stroke and fill. Then you could use semi-transparent colors.

From the documentation:

CGPathCreateCopyByStrokingPath

Creates a stroked copy of another path.

CGPathRef CGPathCreateCopyByStrokingPath(
                                         CGPathRef path,
                                         const CGAffineTransform *transform,
                                         CGFloat lineWidth,
                                         CGLineCap lineCap,
                                         CGLineJoin lineJoin,
                                         CGFloat miterLimit 
                                         ); 

Parameters
path
The path to copy.

transform
A pointer to an affine transformation matrix, or NULL if no transformation is needed. If specified, Quartz applies the transformation to elements of the converted path before adding them to the new path.

lineWidth
The line width to use, in user space units. The value must be greater than 0.

lineCap
A line cap style constant—kCGLineCapButt (the default), kCGLineCapRound, or kCGLineCapSquare. See “CGLineCap”.

lineJoin
A line join value—kCGLineJoinMiter (the default), kCGLineJoinRound, or kCGLineJoinBevel. See “CGLineJoin”.

miterLimit
The miter limit to use.