User Interface Customization in iOS 6

Note from Ray: This is the fifth iOS 6 tutorial in the iOS 6 Feast! In this tutorial, we’re updating one of our older tutorials to iOS 6 so it’s fully up-to-date with the latest features like the new UIKit controls that can be customized in iOS 6. Parts of this tutorial come from Steve […] By .

Leave a rating/review
Save for later
Share

Learn how to customize your UIKit controls in iOS 6!

Note from Ray: This is the fifth iOS 6 tutorial in the iOS 6 Feast! In this tutorial, we’re updating one of our older tutorials to iOS 6 so it’s fully up-to-date with the latest features like the new UIKit controls that can be customized in iOS 6.

Parts of this tutorial come from Steve Baranski and Adam Burkepile’s chapters in iOS 5 and iOS 6 by Tutorials, although the book covers a lot more than this simple example, such as beautifying table views, dynamically theming your apps, and more. Enjoy!

Update 9/22/12: Fully updated for iOS 6 by Adam Burkepile.

10/12/11: Original post by Steve Baranski.

To be successful on the App Store, your app needs to stand out. The vanilla user-interface “look and feel” provided by Apple just doesn’t cut it any more in a crowded market.

Many of the most popular apps on the App Store present standard iOS UI elements in a non-standard fashion:

  • Twitter employs a custom UITabBar
  • Instagram uses both a custom UITabBar and a custom UINavigationBar
  • Epicurious for iPad customizes elements of the standard split-view interface

Create a cool custom user interface with iOS 6's new UIKit and UIAppearance APIs!

Create a cool custom user interface with iOS 5's new UIKit and UIAppearance APIs!

Prior to iOS 5, many developers had to take somewhat unconventional approaches to achieve these results. Although subclassing and overriding drawRect: was the recommended approach, many resorted to the dreaded “method swizzling”.

But with iOS 5 and above, those dark days are over! iOS 5 added a bunch of new APIs you can use to easily customize the appearance of various UIKit controls, and iOS 6 added even more.

To illustrate some of these new APIs, in this tutorial we’re going to take a “plain vanilla” app about surfing trips and customize the UI to get a more “beach-themed” look-and-feel.

To get the most out of this tutorial, you need to know the basics of iOS development first. If you are new to iOS development, you should check out some of the other tutorials on this site first.

Getting Started

To begin, download the the starter project. I’ve created a simple app for you to start with so you can focus on the meat of this tutorial – UIKit customization.

Once you open up the project, take a look around the code and XIBs. You’ll see that the primary view presents a list of our surfing trips, and the detail view allows us to capture more information about each trip individually.

With that context, Build & Run the app (Cmd-R) to see what you have to start with.

Screen Shot 2012 09 15 at 8 37 50 PMScreen Shot 2012 09 15 at 8 37 44 PM

Huh. Yes, this app is functional, but it’s hardly representative of the fun one would expect to have on a surfing trip. Let’s survey the scene in more detail.

Let’s start with the detail page. Things look pretty standard there, eh?

A plain UIBarButtonItem on the UINavigationBar at the top, stock UITabBar elements at the bottom, and the following “standard” data entry components including the following:

  • UILabels with “System” Helvetica fonts
  • UITextField
  • UISlider
  • UISwitch
  • UISegmentedControl
  • UINavigationBarShadow
  • UIStepper
  • UIProgressView
  • UIPageControl

In this tutorial, you’ll completely customize the detail screen to give it some style, using the new APIs available in iOS 5 and 6. So with an idea of what’s in store, let’s convert this app from “zero” to “hero”.

Adding a Background Image

If you open up the Images folder in your project, you’ll see that you already have some images you can use to customize the UI included in the project – you just need to modify the code to make use of them.

Inside the images folder is a file called bg_sand.png. We’re going to start our UI customization by making this the background image in the detail view.

Open DetailViewController.m and create a viewDidLoad method like this:

- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.view.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"bg_sand"]];
}

If you aren’t familiar with this technique, you can actually make a “color” based on an image like you see here. This is an easy way to set the background of a view, because there’s no “backgroundImage” property, but there is a “backgroundColor” property!

Compile and run to verify that it worked:

Screen Shot 2012 09 16 at 2 12 18 AM

I can feel the sand between our toes already!

Customizing UINavigationBar

If you look inside the images folder, you’ll see two images that you want to use to customize the navigation bar: surf_gradient_textured_32.png and surf_gradient_textured_44.png.

You want to repeat these from left to right across the navigation bar. there are two different heights because the height of the navigation bar shrinks when the phone goes into landscape.

iOS 5 offers two new APIs that can help us with this:

  • UINavigationBar has a new backgroundImage property you can use to set a custom background image like this.
  • UIImage has a new resizableImageWithCapInsets method you can use to create a resizable image. The cap insets allow you to specify the portions of the image that should not be repeated, such as if you have rounded corners for a button on the edges that shouldn’t be repeated.

You could go into the detail view and use these new APIs to set the navigation bar’s background image directly. But then you’d have to go and do the same thing inside our list view, and any other views you might have in our app!

Obviously this would get old quick. Recognizing this, iOS 5 offers a cool new feature that allows us to customize user interface elements once, allowing it to “stand in” for other elements within the same level in the containment hierarchy.

So starting with the navigation bar, we’re going to use this concept of the “appearance proxy” to customize some elements that will be repeated throughout the app.

Let’s see how it looks. Inside SurfsUpAppDelegate.m, create a new method right above application:didFinishLaunchingWithOptions:

- (void)customizeAppearance
{
    // Create resizable images
    UIImage *gradientImage44 = [[UIImage imageNamed:@"surf_gradient_textured_44"]
                                resizableImageWithCapInsets:UIEdgeInsetsMake(0, 0, 0, 0)];
    UIImage *gradientImage32 = [[UIImage imageNamed:@"surf_gradient_textured_32"]
                                resizableImageWithCapInsets:UIEdgeInsetsMake(0, 0, 0, 0)];
    
    // Set the background image for *all* UINavigationBars
    [[UINavigationBar appearance] setBackgroundImage:gradientImage44
                                       forBarMetrics:UIBarMetricsDefault];
    [[UINavigationBar appearance] setBackgroundImage:gradientImage32
                                       forBarMetrics:UIBarMetricsLandscapePhone];
    
    // Customize the title text for *all* UINavigationBars
    [[UINavigationBar appearance] setTitleTextAttributes:
     [NSDictionary dictionaryWithObjectsAndKeys:
      [UIColor colorWithRed:255.0/255.0 green:255.0/255.0 blue:255.0/255.0 alpha:1.0],
      UITextAttributeTextColor,
      [UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:0.8],
      UITextAttributeTextShadowColor,
      [NSValue valueWithUIOffset:UIOffsetMake(0, -1)],
      UITextAttributeTextShadowOffset,
      [UIFont fontWithName:@"Arial-Bold" size:0.0],
      UITextAttributeFont,
      nil]];
}

The first two lines create stretchable images using the resizableImageWithCapInsets method discussed earlier. Note that this method replaces stretchableImageWithLeftCapWidth:topCapHeight:, which is now deprecated.

For the cap insets, you basically specify the fixed region of a given image in top, left, bottom, right. What’s left is stretched over the remainder of the region to which the image is applied. In this particular image you want the whole thing stretched, so you pass 0 for all of the fixed caps.

The next two lines invoke the appearance proxy, designating these stretchable images as background images, for the bar metrics specified.

The last line stylizes the title that appears in our detail view. To do so, you pass a dictionary of title text attributes. The available keys include the following:

  • UITextAttributeFont
  • UITextAttributeTextColor
  • UITextAttributeTextShadowColor
  • UITextAttributeTextShadowOffset

Almost done – just add the line to call this method at the top of application:didFinishLaunchingWithOptions:

[self customizeAppearance];

Compile and run, and now you should see the navigation bar has the teal background image applied in both orientations, with stylized title text as well!

Screen Shot 2012 09 16 at 3 36 19 PM