views:

642

answers:

1

UPDATE: I tried implementing the method specified by Peter and am getting incorrect shadowing. What is wrong?

alt text

CGContextSetShadowWithColor(c, CGSizeMake(4, 4), kAudioThumbShadowBlur, [[UAColor blackColor] CGColor]);
    CGContextFillPath(c);

    CGMutablePathRef path = CGPathCreateMutable();
    CGPathMoveToPoint(path, NULL, minx, midy);
    CGPathAddArcToPoint(path, NULL, minx, miny, midx, miny, kDefaultMargin);
    CGPathAddArcToPoint(path, NULL, maxx, miny, maxx, midy, kDefaultMargin);
    CGPathAddArcToPoint(path, NULL, maxx, maxy, midx, maxy, kDefaultMargin);
    CGPathAddArcToPoint(path, NULL, minx, maxy, minx, midy, kDefaultMargin);
    CGPathCloseSubpath(path);


    // Fill and stroke the path
    CGContextSaveGState(c);
    CGContextAddPath(c, path);
    CGContextClip(c);


    myGradient = CGGradientCreateWithColorComponents(myColorspace, components, locations, 2);
    CGContextDrawLinearGradient(c, myGradient, CGPointMake(minx,miny), CGPointMake(minx,maxy), 0);

    CGContextAddPath(c, path);
    CGPathRelease(path);
    CGContextStrokePath(c);
    CGContextRestoreGState(c);





ORIGINAL QUESTION: I am looking to draw a natural looking shadow around the bottom of a custom rounded cell item I make in CoreGraphics using this code:

...
    CGMutablePathRef path = CGPathCreateMutable();
    CGPathMoveToPoint(path, NULL, minx, miny);
    CGPathAddArcToPoint(path, NULL, minx, maxy, midx, maxy, kDefaultMargin);
    CGPathAddArcToPoint(path, NULL, maxx, maxy, maxx, miny, kDefaultMargin);
    CGPathAddLineToPoint(path, NULL, maxx, miny);
    CGPathAddLineToPoint(path, NULL, minx, miny);
    CGPathCloseSubpath(path);

    // Fill and stroke the path
    CGContextSaveGState(c);
    CGContextAddPath(c, path);
    CGContextClip(c);

    myGradient = CGGradientCreateWithColorComponents(myColorspace, components, locations, 2);
    CGContextDrawLinearGradient(c, myGradient, CGPointMake(minx,miny), CGPointMake(minx,maxy), 0);

    CGContextAddPath(c, path);
    CGPathRelease(path);
    CGContextStrokePath(c);
    CGContextRestoreGState(c);
...

I want to apply the shadow around the outside of this path, either before or after the gradient fill. What is the best way to go about doing this?

+2  A: 

A gradient draw doesn't count as a fill, so, first, set the shadow and do a solid-color fill. Then, draw over the solid-color fill with the gradient and clipped stroke.

Peter Hosey
This makes sense, but would't the shadow be straight under the curved path? I am looking for the shadow to also curve naturally under the curved path
coneybeare
Why would it be straight (I assume you mean rectangular) under a curved fill?
Peter Hosey
I guess I am confused :) After trying it out, it works great. thanks - Matt
coneybeare
I jumped the gun… it seems it does not work as expected. Updating question…
coneybeare
coneybeare: You need to fill the path you want shadowed. That means you need to draw the path first. (And save/restore gstate around it, since filling will clear the path.)
Peter Hosey
Peter, could you maybe update your answer with a code sample, I have tried many ways to get this right but cant seem to get it. You seem to know how to do it.
coneybeare
How to do it: Set the shadow, then create and add the path, then fill it. Your current code tries to fill the path *before* it adds the path to the context's current path, which is why it doesn't work; you need to add the path to the current path first, then fill it. This will also make your “Fill and stroke the path” comment accurate, which it currently isn't.
Peter Hosey