Archive for the ‘tutorial’ Category

Feb20

Creating Reusable UIViews with a Drop Shadow [Tutorial]

Update: I’ve updated the post to reflect what code requires iOS 4.0 and later.  Basically, the layer properties for the drop shadow.

I’m working on an internal iPhone application for my employer.  It’s data-centric, as I’m sure most enterprise grade apps are, and as such consists mostly of UITableViews so users can view and drill into each subsequent level of detail.

One requirement was to have summary data points from previous screens on each view.  Nothing mind blowing that a tableHeaderView couldn’t solve.  However, a couple of these summary views would be reused and had several data points.  To complicate things, I needed a drop shadow to distinguish the header from the table (they are the same color in this particular case).

I decided to subclass UIView and do the layout in IB.  This kept the code clean and was a BREEZE to lay out (and change layouts as we’ve now done several times).  Unfortunately, it wasn’t as straight-forward as I originally thought.  However, with a little help from Ray Wenderlich, I was able to get it implemented.  This is a quick tutorial for those out there that may be struggling with something similar.  The technique outlined below is only available for apps targeting iOS devices running at least 4.0.

Create the project

To get started, create a view based application – I named mine ReusableTableHeaders.  Within ReusableTableHeadersViewController.h, change the parent class from UIViewController to UITableViewController and define two instance variables – tblData (UITableView) and data (NSArray).  tblData will be our table view (so remember to add IBOutlet) and data will be a simple array of information to display.  Before leaving ReusableTableHeadersViewController.h, add UITableViewDelegate and UITableViewDataSource to the interface definition.

Pop over to the implementation file.  The first thing I always do is synthesize and update dealloc accordingly.  This tends to save me from myself later.  Within the viewDidLoad method, fill data with some values.  I went with the oh-so-clever ‘Value 1′, ‘Value 2′, and ‘Value 3′.  Once complete, open up IB and we’ll set the table view up before we build and run to make sure we’re ok.

Within IB, delete the UIView that’s currently there and replace it with a UITableView.  Connect that to both tblData and view within the File Owner.  You’ll also want to set the File Owner as the data source and delegate.  I changed my table view style to grouped and added a background.  That’s totally your call.

Here’s a quick shot of what IB looks like:

Build and Run to make sure we’re on the same page thus far.  Here’s a quick shot of what I get.

Subclassing UIView

Now that we have the foundation in place, let’s get started on the header view.  Add a new Objective-C class to your project.  When prompted to choose your type, you’ll also want to set the subclass option to UIView.  I named my class HeaderView. We’re going to go ahead and add a nib as well.  Add a new view based nib to your project – I named mine HeaderView.xib.

Once your class files and nib are created, define a UILabel instance variable within the .h (mine is titled lblTitle) and set it as an outlet.  Now, hop over to the implementation file, synthesize, and update the dealloc method.  Also, be sure to include <QuartzCore/QuartzCore.h>.  Within the initWithFrame method, add the following code:

The code is pretty straight-forward.  The first block loads the HeaderView nib file and sets this itself equal to the loaded nib.  The second block of code handles setting the drop shadow (note: the layer.shadow* related code only works in iOS 4.0 and above).  Manipulating the shadow color can produce some pretty cool effects but we’ll stick with the generic black for now.  With that done, it’s time to set our nib up in IB.

Setting up the view in IB

Unfortunately, and I’m not sure why, you can’t alter the height of the default view when creating a view based nib.  My solution, delete the existing view and add a new one.  Set your desired dimensions – for this tutorial we go with 320 by 60.  You’ll also want to drag another UIView and UILabel into the nib as subviews.  I actually added two UILabels – a ‘title’ label and the label I’ll update programmatically.

Select the top level view and open Inspector.  Set the class to your custom class – HeaderView.  While in the Inspector, set the background color clear.

Now select the UIView subview and change the height dimension to just slightly less than our ‘parent’ view.  For this tutorial, I went with a difference of 5 points – 320 by 55 – and then aligned the two UIViews at the top.  Change the background color to whatever you’d like your header to be.

Link up one of the UILabel’s to lblTitle you defined in HeaderView.h and you should be all set.

Using the view

First things first, import your custom class within ReusableTableHeadersViewController.  From here, you have several options about where to implement your custom view.  The requirement I needed to satisfy required that I use the viewWillAppear method as information could be updated as views pushed and popped.  I wanted to ensure I had the most up-to-date information presented.  For this tutorial, we’ll load it within viewDidLoad.

Walking through what we just did; we instantiate the view, set the title label, and then load it into our table view as the header.

Wrapping Up

And we’re done! Build and run and you should have something that resembles the screenshot below!

Here’s the project files: ReusableTableHeaders.zip.

Well, that’s my first iOS tutorial.  Hope it helps and be sure to let me know what works and what doesn’t work in the comments.  I hope to have several more over the course of the year.

Did you like this? Share it: