[iphone] How do I draw a shadow under a UIView?


A by far easier approach is to set some layer attributes of the view on initialization:

self.layer.masksToBounds = NO;
self.layer.shadowOffset = CGSizeMake(-15, 20);
self.layer.shadowRadius = 5;
self.layer.shadowOpacity = 0.5;

You need to import QuartzCore.

#import <QuartzCore/QuartzCore.h>

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();
    CGContextSetShadow(currentContext, CGSizeMake(-15, 20), 5);
    [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?

Swift 3

self.paddingView.layer.masksToBounds = false
self.paddingView.layer.shadowOffset = CGSize(width: -15, height: 10)
self.paddingView.layer.shadowRadius = 5
self.paddingView.layer.shadowOpacity = 0.5

Same solution, but just to remind you: You can define the shadow directly in the storyboard.


Simple and clean solution using Interface Builder

Add a file named UIView.swift in your project (or just paste this in any file) :

import UIKit

@IBDesignable extension UIView {

    /* The color of the shadow. Defaults to opaque black. Colors created
    * from patterns are currently NOT supported. Animatable. */
    @IBInspectable var shadowColor: UIColor? {
        set {
            layer.shadowColor = newValue!.CGColor
        get {
            if let color = layer.shadowColor {
                return UIColor(CGColor:color)
            else {
                return nil

    /* The opacity of the shadow. Defaults to 0. Specifying a value outside the
    * [0,1] range will give undefined results. Animatable. */
    @IBInspectable var shadowOpacity: Float {
        set {
            layer.shadowOpacity = newValue
        get {
            return layer.shadowOpacity

    /* The shadow offset. Defaults to (0, -3). Animatable. */
    @IBInspectable var shadowOffset: CGPoint {
        set {
            layer.shadowOffset = CGSize(width: newValue.x, height: newValue.y)
        get {
            return CGPoint(x: layer.shadowOffset.width, y:layer.shadowOffset.height)

    /* The blur radius used to create the shadow. Defaults to 3. Animatable. */
    @IBInspectable var shadowRadius: CGFloat {
        set {
            layer.shadowRadius = newValue
        get {
            return layer.shadowRadius

Then this will be available in Interface Builder for every view in the Utilities Panel > Attributes Inspector :

You can easily set the shadow now.

- The shadow won't appear in IB, only at runtime.
- As Mazen Kasser said

To those who failed in getting this to work [...] make sure Clip Subviews (clipsToBounds) is not enabled

You can use my utility function created for shadow and corner radius as below:

- (void)addShadowWithRadius:(CGFloat)shadowRadius withShadowOpacity:(CGFloat)shadowOpacity withShadowOffset:(CGSize)shadowOffset withShadowColor:(UIColor *)shadowColor withCornerRadius:(CGFloat)cornerRadius withBorderColor:(UIColor *)borderColor withBorderWidth:(CGFloat)borderWidth forView:(UIView *)view{

    // drop shadow
    [view.layer setShadowRadius:shadowRadius];
    [view.layer setShadowOpacity:shadowOpacity];
    [view.layer setShadowOffset:shadowOffset];
    [view.layer setShadowColor:shadowColor.CGColor];

    // border radius
    [view.layer setCornerRadius:cornerRadius];

    // border
    [view.layer setBorderColor:borderColor.CGColor];
    [view.layer setBorderWidth:borderWidth];

Hope it will help you!!!

Swift 3

extension UIView {
    func installShadow() {
        layer.cornerRadius = 2
        layer.masksToBounds = false
        layer.shadowColor = UIColor.black.cgColor
        layer.shadowOffset = CGSize(width: 0, height: 1)
        layer.shadowOpacity = 0.45
        layer.shadowPath = UIBezierPath(rect: bounds).cgPath
        layer.shadowRadius = 1.0