I am trying to draw an inset shadow inside a rounded rectangle by clipping away the stroke of a path using a clipping mask, leaving only the shadow behind. The ultimate goal is to approximate the inset look of things in the notification center.
I'm failing. CGContextClipToMask is simply not working, which is especially maddening because I'm using this same technique elsewhere in the project, and it works fine there. Here is my drawing code:
const CGFloat cornerRadius = 5.0f;
CGContextRef context = UIGraphicsGetCurrentContext();
// Draw background color
[[UIColor colorWithWhite:0.2 alpha:0.5] setFill];
UIBezierPath* background = [UIBezierPath bezierPathWithRoundedRect:self.bounds cornerRadius:cornerRadius];
[background fill];
// Draw the inner shadow
UIImage* mask;
UIGraphicsBeginImageContext(self.bounds.size);
{{
CGContextRef igc = UIGraphicsGetCurrentContext();
[[UIColor blackColor] setFill];
CGContextFillRect(igc, self.bounds);
// Inset the mask by a ridiculous degree just to be sure that it's working
UIBezierPath* insetMask = [UIBezierPath bezierPathWithRoundedRect:CGRectInset(self.bounds, 20, 20) cornerRadius:cornerRadius];
[[UIColor whiteColor] setFill];
[insetMask fill];
mask = UIGraphicsGetImageFromCurrentImageContext();
}}
UIGraphicsEndImageContext();
CGContextSaveGState(context);
{{
CGContextClipToMask(context, self.bounds, mask.CGImage);
[[UIColor whiteColor] setStroke];
CGContextSetShadow(context, CGSizeMake(0, 1), 1);
[background stroke];
}}
CGContextRestoreGState(context);
If I were to guess at what's wrong, I'd say I am somehow violating the prerequisites laid out in the docs:
If
mask
is an image, then it must be in the DeviceGray color space, may not have an alpha component, and may not be masked by an image mask or masking color.
However, I have discovered no way to verify whether this is the case, let alone correct it if so.
TIA for any help you can offer!
(I am running the app on an iPhone 4S running iOS 6.)