by

Assumptions

You have enough familiarity with UIKit and Xcode to create projects and UIViews. If not, consider starting with Recipe 1 and reviewing Familiarizing Yourself With Xcode

Shadows!

Even the slightest drop shadow here and there can dramatically improve the look of your application’s UI, but at what cost?

Today we will cover adding shadows to UIViews of all kinds. Feel free to check out the source code for this recipe available on our GitHub page.

Step 1: Setup A Dummy Project

Open Xcode, create a new project using the single view based iOS application template. Name it something like “Shadows” and be sure to uncheck Use Storyboards and check Use Automatic Reference Counting. I also selected iPhone from the devices drop-down menu, just to keep things simple.

Next, open ViewController.xib and add a generic UIView to the view controller’s view.

and add a generic UIView to the view controller’s view. Let’s go ahead and turn off Autolayout for this xib file by opening the File Inspector Option + CMD + 1 and unchecking Use Autolayout.

and unchecking With the newly added UIView selected, open the size inspector Option + CMD + 5 and remove all the springs and struts from the view. Then, resize it to 200×200 and center it within the superview.

Next add an outlet for the view in ViewController.h, then connect it in viewController.xib by Control + Dragging from File’s Owner to the view and selecting sampleView from the HUD.

@property ( nonatomic, strong ) IBOutlet UIView * sampleView;

Next change the background color of sampleView in viewController.xib to blue by selecting it in the object tree and then changing the background color in the attributes inspector Option + CMD + 4 .

in viewController.xib to blue by selecting it in the object tree and then changing the background color in the attributes inspector . Build and run the project CMD + R, you should see a blue square in the center of the screen if everything has been setup successfully.

Step 2: Adding A Basic Shadow

First, we need to add the QuartzCore framework to the project. This is where Core Animation lives, which is what we will be using to create our shadows. To add QuartzCore to the project, select the project file from the source list on the left, then select the Build Phases tab in the center and open the Link Libraries With Binary section.

Press the + button in the lower left corner of the section, then type QuartzCore in the search field, select it and press Add in the lower right corner.

Open ViewController.h and add the following import for QuartzCore at the top. This will allow us to use Core Animation API.

#import <QuartzCore/QuartzCore.h>

Now open viewController.m, In the viewDidLoad method we will add our shadow code.

- ( void ) viewDidLoad

{

[ super viewDidLoad ] ;



//Adds a shadow to sampleView

CALayer * layer = self.sampleView.layer;

layer.shadowOffset = CGSizeMake ( 1 , 1 ) ;

layer.shadowColor = [ [ UIColor blackColor ] CGColor ] ;

layer.shadowRadius = 4.0f;

layer.shadowOpacity = 0.80f;

layer.shadowPath = [ [ UIBezierPath bezierPathWithRect : layer.bounds ] CGPath ] ;

}

Build & run the app, you now have a shadow around the view!

Step 3: Shadows Explained

As seen in the last step there are a few different properties needed when adding a shadow using Core Animation. If your are not familiar with Core Animation don’t worry, just try to focus on the shadow code and not the CALayer on the view.

shadowOffset is a CGSize representing how far to offset the shadow from the path.

is a CGSize representing how far to offset the shadow from the path. shadowColor is the color of the shadow. Shadow colors should always be opaque, because the opacity will be set by the shadowOpacity property. The shadowColor property is a CGColor not a UIColor.

is the color of the shadow. Shadow colors should always be opaque, because the opacity will be set by the shadowOpacity property. The shadowColor property is a CGColor not a UIColor. shadowRadius is the width of the shadow along the shadow path

is the width of the shadow along the shadow path shadowOpacity determines the opacity of the shadow.

determines the opacity of the shadow. shadowPath is probably the most important of the properties. While a shadow can be drawn without specifying a path, for performance reasons you should always specify one. This path tells Core Animation what the opaque regions of the view are, and without it, things slow down severely! It is a CGPath, which is most easily created using UIBezierPath (iOS only) as shown in step 2.

Step 4: Fun With Shadow Paths

One of the cool things about adding shadows using Core Animation is that the shadowPath doesn’t have to be a square! Let’s create a quick method that creates a shadowPath that makes the view appear to bend in the center.

- ( CGPathRef ) fancyShadowForRect : ( CGRect ) rect

{

CGSize size = rect.size;

UIBezierPath * path = [ UIBezierPath bezierPath ] ;



//right

[ path moveToPoint : CGPointZero ] ;

[ path addLineToPoint : CGPointMake ( size.width, 0.0f ) ] ;

[ path addLineToPoint : CGPointMake ( size.width, size.height + 15.0f ) ] ;



//curved bottom

[ path addCurveToPoint : CGPointMake ( 0.0 , size.height + 15.0f )

controlPoint1 : CGPointMake ( size.width - 15.0f, size.height )

controlPoint2 : CGPointMake ( 15.0f, size.height ) ] ;



[ path closePath ] ;



return path.CGPath;

}

Add this method to viewController.m and then change viewDidLoad as follows

- ( void ) viewDidLoad

{

[ super viewDidLoad ] ;



//Adds a shadow to sampleView

CALayer * layer = self.sampleView.layer;



//changed to zero for the new fancy shadow

layer.shadowOffset = CGSizeZero;



layer.shadowColor = [ [ UIColor blackColor ] CGColor ] ;



//changed for the fancy shadow

layer.shadowRadius = 2.0f;



layer.shadowOpacity = 0.80f;



//call our new fancy shadow method

layer.shadowPath = [ self fancyShadowForRect : layer.bounds ] ;

}

Build and run, look at the new fancy shadow!

Final Thoughts

Adding shadows to views isn’t very hard using Core Animation and it can really make your app look great! Just don’t over do it! Remember shadows, even with a shadow path specified, do affect performance negatively so use them appropriately. If you are interested in more cool shadow paths take a look at this posting!

As always, please let us know if you have any questions or comments!