I want to add a shadow around the OUTSIDE edge of a HOLLOW CGPath (those two words being critical: outside + hollow :) ).
Apple's shadow implementation only allows you to do "filled" shadows.
So ... how to clip-away the inside part of the shadow itself? If it were a render call, I'd call CGContextSetClip* methods to clip it to where I wanted it ... but I can't see how you'd get at it, since it's neither a render call, nor a CALayer itself.
(an unfortunate consequence of Apple "hiding" it as a set of magic variables, I guess?)
NB: this is iOS only - IIRC on Mac you have direct access to the filters used to create shadows, so you can create your own (arbitrary) shadows by hand.
UPDATE:
I worked out how to clip to show only the INNER part of the shadow: set the "layer.mask", to be a new layer that's a clone of the current layer (i.e. same path), and set the path fillcolor to anything with full alpha.
This is the opposite of what I'm trying, so if I could figure a way to get the mask layer to flip alpha (0 becomes 1, 1 becomes 0), I'd be there...
Assuming you have a method:
-(CAShapeLayer*) cloneShapeLayer; // creates a new CAShapeLayer and copies the values
...then do this:
i.e. in code:
CAShapeLayer* maskLayer = [originalLayer cloneShapeLayer];
// got to make it a bit bigger if your original path reaches to the edge
// since the shadow needs to stretch "outside" the frame:
CGFloat shadowBorder = 50.0;
maskLayer.frame = CGRectInset( maskLayer.frame, - shadowBorder, - shadowBorder );
maskLayer.frame = CGRectOffset( maskLayer.frame, shadowBorder/2.0, shadowBorder/2.0 );
maskLayer.fillColor = [UIColor blackColor].CGColor;
maskLayer.lineWidth = 0.0;
maskLayer.fillRule = kCAFillRuleEvenOdd;
CGMutablePathRef pathMasking = CGPathCreateMutable();
CGPathAddPath(pathMasking, NULL, [UIBezierPath bezierPathWithRect:maskLayer.frame].CGPath);
CGAffineTransform catShiftBorder = CGAffineTransformMakeTranslation( shadowBorder/2.0, shadowBorder/2.0);
CGPathAddPath(pathMasking, NULL, CGPathCreateCopyByTransformingPath(maskLayer.path, &catShiftBorder ) );
maskLayer.path = pathMasking;
shapeLayer.mask = maskLayer;
NB: this actually works, except that the shadow seems to get enlarged a little compared to when I wasn't masking. Oh well.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With