Question

I'm trying to draw a UIBezierPathShape in iOS7 then apply a shadow. This works great except that when I stroke the path, the stroke shows up behind the shape. How can I rectify this?

Code:

- (void)drawDiamondWithCount:(NSUInteger)count inRect:(CGRect)rect {
    CGContextRef ctx = UIGraphicsGetCurrentContext();
    UIGraphicsPushContext(ctx);
    UIEdgeInsets insets = UIEdgeInsetsMake(cardEdgeInsetTop, cardEdgeInsetRight, cardEdgeInsetBottom, cardEdgeInsetLeft);
    CGRect insetsRect = UIEdgeInsetsInsetRect(rect, insets);

    CGFloat shapeHeight = insetsRect.size.height / (double) count;
    CGRect shapeRect;
    for (NSUInteger i = 0; i < count; ++i) {
        // Get the rect for the single shape
        int numRemainingShapes = count - i - 1;
        CGFloat remainingBottomSpace = numRemainingShapes * shapeHeight;
        insets = UIEdgeInsetsMake(i * shapeHeight + shapeEdgeInsets, 0, remainingBottomSpace + shapeEdgeInsets, 0);
        shapeRect = UIEdgeInsetsInsetRect(insetsRect, insets);
        UIBezierPath *path = [self getDiamondPath:shapeRect];
        [[UIColor redColor] setFill];
        [[UIColor blackColor] setStroke];
        UIGraphicsPushContext(ctx);
        CGContextSetShadow(ctx, CGSizeMake(5, 2), 5);
        [path fill];
        UIGraphicsPopContext();
        //[path stroke];
    }
    UIGraphicsPopContext();
}

This gives me what I want, minus the stroke This gives me what I want, minus the stroke

Uncommenting [path stroke] gives me this. I want the stroke, but don't want to see it behind the shape.

enter image description here

Was it helpful?

Solution

I suspect that instead of UIGraphicsPushContext and UIGraphicsPopContext, I think you want CGContextSaveGState and CGContextRestoreGState:

// create context and configure

CGContextRef ctx = UIGraphicsGetCurrentContext();
[[UIColor redColor] setFill];
[[UIColor blackColor] setStroke];

// create path

UIBezierPath *path = ...;
path.lineJoinStyle = kCGLineJoinMiter;
path.lineWidth = 2.0;

// fill the center with shadow

CGContextSaveGState(ctx);
CGContextSetShadow(ctx, CGSizeMake(5, 2), 5);
[path fill];
CGContextRestoreGState(ctx);

// stroke border without shadow

CGContextSetLineWidth(ctx, 2.0);
[path stroke];

With UIGraphicsPushContext and UIGraphicsPopContext you get:

line shadow

With CGContextSaveGState and CGContextRestoreGState you get:

enter image description here

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top