Fraser Speirs Fraser Speirs - 1 month ago 12
iOS Question

How do I draw a shadow under a UIView?

I'm trying to draw a shadow under the bottom edge of a

UIView
in Cocoa Touch. I understand that I should use
CGContextSetShadow()
to draw the shadow, but the Quartz 2D programming guide is a little vague:


  1. Save the graphics state.

  2. Call the function
    CGContextSetShadow
    , passing the appropriate values.

  3. Perform all the drawing to which you want to apply shadows.

  4. Restore the graphics state



I've tried the following in a
UIView
subclass:

- (void)drawRect:(CGRect)rect {
CGContextRef currentContext = UIGraphicsGetCurrentContext();
CGContextSaveGState(currentContext);
CGContextSetShadow(currentContext, CGSizeMake(-15, 20), 5);
CGContextRestoreGState(currentContext);
[super drawRect: rect];
}


..but this doesn't work for me and I'm a bit stuck about (a) where to go next and (b) if there's anything I need to do to my
UIView
to make this work?

Answer

In your current code, you save the GState of the current context, configure it to draw a shadow .. and the restore it to what it was before you configured it to draw a shadow. Then, finally, you invoke the superclass's implementation of drawRect: .

Any drawing that should be affected by the shadow setting needs to happen after

CGContextSetShadow(currentContext, CGSizeMake(-15, 20), 5);

but before

CGContextRestoreGState(currentContext);

So if you want the superclass's drawRect: to be 'wrapped' in a shadow, then how about if you rearrange your code like this?

- (void)drawRect:(CGRect)rect {
    CGContextRef currentContext = UIGraphicsGetCurrentContext();
    CGContextSaveGState(currentContext);
    CGContextSetShadow(currentContext, CGSizeMake(-15, 20), 5);
    [super drawRect: rect];
    CGContextRestoreGState(currentContext);
}