7

With core graphics, is it possible to stroke the inside of a path? As opposed to the line weight being drawn half on the outside and half on the inside of a stroked path?

The reason being it would be easier to control the visible thickness of the stroke if say part of a view is on the screen edge and part is not. The part on the screen edge gets cut off, while the view edge that is fully on screen looks thicker (as both sides if the stroke are visible).

enter image description here

OWolf
  • 5,012
  • 15
  • 58
  • 93

2 Answers2

15

Clip to the path before you stroke it.

Kurt Revis
  • 27,695
  • 5
  • 68
  • 74
  • Thanks! Could you look at my "answer" above and comment. This method does not quite work. The stroke does not draw at all. What is clip to path, the method name? – OWolf Jan 12 '13 at 15:28
  • You're close. [The documentation for `CGContextClip()`](https://developer.apple.com/library/ios/documentation/graphicsimaging/reference/CGContext/Reference/reference.html#//apple_ref/c/func/CGContextClip) says: "After determining the new clipping path, the function resets the context’s current path to an empty path." That explains why `CGContextDraw` doesn't draw anything -- you need to add the path to the context again, before you stroke. – Kurt Revis Jan 12 '13 at 19:18
  • Using a [`CGPath`](https://developer.apple.com/library/ios/#documentation/graphicsimaging/Reference/CGPath/Reference/reference.html#//apple_ref/c/tdef/CGPathRef) or [`UIBezierPath`](http://developer.apple.com/library/ios/#documentation/uikit/reference/UIBezierPath_class/Reference/Reference.html) would make that process easier -- you could create the path once, then use it twice. – Kurt Revis Jan 12 '13 at 19:19
  • Nice! Short and crisp! Thanks a lot! – the_critic Apr 14 '15 at 20:15
6

This draws no stroke:

- (void)drawRect:(CGRect)rect
{
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetStrokeColorWithColor(context, [UIColor darkGrayColor].CGColor);
    CGContextSetLineWidth(context, 14);
    CGRect rrect = CGRectMake(CGRectGetMinX(rect), CGRectGetMinY(rect), CGRectGetWidth(rect), CGRectGetHeight(rect));
    CGFloat radius = 30;
    CGFloat minx = CGRectGetMinX(rrect), midx = CGRectGetMidX(rrect), maxx = CGRectGetMaxX(rrect);
    CGFloat miny = CGRectGetMinY(rrect), midy = CGRectGetMidY(rrect), maxy = CGRectGetMaxY(rrect);
    CGContextMoveToPoint(context, minx, midy);
    CGContextAddArcToPoint(context, minx, miny, midx, miny, radius);
    CGContextAddArcToPoint(context, maxx, miny, maxx, midy, radius);
    CGContextAddArcToPoint(context, maxx, maxy, midx, maxy, radius);
    CGContextAddArcToPoint(context, minx, maxy, minx, midy, radius);
    CGContextClosePath(context);
    CGContextClip(context);
    CGContextDrawPath(context, kCGPathStroke);
}

EDIT: This is what worked (according to the correct answer):

- (void)drawRect:(CGRect)rect
{
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetStrokeColorWithColor(context, [UIColor darkGrayColor].CGColor);
    CGContextSetFillColorWithColor(context, [UIColor blackColor].CGColor);
    CGContextSetLineWidth(context, 14);
    CGRect pathRect = CGRectMake(10, 10, rect.size.width -20, rect.size.height -20);
    CGPathRef path = [UIBezierPath bezierPathWithRoundedRect:pathRect cornerRadius:20].CGPath;
    CGContextAddPath(context, path);
    CGContextClip(context);
    CGContextAddPath(context, path);
    CGContextDrawPath(context, kCGPathEOFillStroke);

}
OWolf
  • 5,012
  • 15
  • 58
  • 93