Customization of UIKit Controls

Before the launch of iOS 5, the customization of some UI elements (navigation bars, switches, etc.) was possible only writing a lot of code, subclassing or adding categories for each UI component. With iOS 5 Apple provided developers with a simpler way of customizing UI elements. Later, with iOS 6, every UI component became quite fully customizable.

Here, I’ll be covering the customization of just some of the UI elements, but after this small tutorial, it should be easy for you to explore by yourself the remaining UI components. For further explanations and more hands-on experience with the latest UI attend an intensive iOS training class with iNVASIVECODE.

A remark before you dive into this tutorial: although it’s true that you can now customize the UI elements easily, you should still stick to the Human Interface Guidelines. Please, review those guidelines and apply some common sense to your customizations.

Fig. 1 highlights the results, one by one, of what we are going to see below.


Fig. 1. The results of the customization

The customization of the UIStepper controller

In iOS 6, Apple introduced a batch of properties that allow you to change the appearance of the UIStepper controller. Item 1 of Fig. 1 is the out-of-the-box version of the UIStepper. Let’s try now to change its appearance.

Tint Color

This is a very simple modification. The tint color of the UIStepper can be modified using the following line of code:

The result can be seen in item 2 of Fig. 1.

Background image

Additionally, you can set an image as background of the UIStepper. Different images can be set depending on the stepper state. Item 3 of Fig. 1 is obtained using the following line of code:

Now, the Apple documentation says: “For good results, image must be a stretchable image”. What does that mean? I will show you this later in the ‘Tiling and stretching images’ section below. Let’s continue with the stepper appearance.

Note: The image used in the above example can be downloaded here: pattern.png and pattern@2x.png.


The divider (the vertical line between the left and right button) can be modified setting a new image and the following line of code shows how to obtain item 4 in Fig 1:

The divider image used in the example is a 5x50 image and you can download it here: divider.png and divider@2x.png.

Increment and Decrement Image

You can set an image for the increment and decrement button depending on the button state with the following lines of code:

Find an example in Fig.1 item 5.

The images used in the above example can be downloaded here: less.png, less@2x.png, more.png, and more@2x.png.

Customizing UISwitch

UISwitch is another control that can be fully customized. We have again a few properties available. Let’s see how to implement them one by one. You can see the default appearance of a UISwitch in Fig. 1 item 6.

Tint Color

Again, this is similar to the UIStepper case:

This line of code produces item 7 of Fig. 1 as a result.

On Tint Color

You can change the color used to tint the appearance of the switch when it is turned on. See the result on Item 8 using the following line of code:

Thumb Tint Color

To change the color of the switch thumb, you can do this (check the result in Item 8 of Fig 1):

Background Image

You can apply a background image to the switch. On and Off states are independent, so you can set a different image for each position. Note that if you want to use this property, you should probably add some text as a hint to the user. See Item 9 of Fig. 1 and check that is kind of difficult to understand what this switch would do compared to the default, where On is clearly written.

Customizing bars

UINavigationBar, UIToolbar and UITabBar have now a shadow image. The navigation bar shows a shadow at the bottom, while a tab bar shows it at the top. The toolbar shows a shadow at the top or at the bottom, depending on its position on the screen. You can change the custom shadow and apply your own shadow image with a simple line of code. Here are some examples and you can see the outcome from the first line of code on Item 10 of Fig. 1:

If you are using a UIToolBar, the shadow image is set depending of the position of the toolbar (top/bottom):

Customizing same elements through the whole application

What we’ve seen so far is really useful and easy to use, but maybe you want to use the same customization of a UI element along your application. Apple gives us a way to customize a UI element and keep that customization in the whole app. To do so, you need to use the UIKit UIAppearance protocol. You customize the appearance of instances of a UI element by sending appearance modification messages to these protocol.

There are two ways to customize appearance for objects:

  • Customization of all instances of a class
  • Customization for instances of a class contained within a container class

Let’s see how to customize the text in the UINavigationBar for the whole application. In the application:didFinishLaunchWithOptions: method in your AppDelegate class, write the following:

Here, we’ve been setting the text attributes of the UINavigationBar title. Then, we’ve passed the dictionary with these attributes to the appearance.
These attributes will be applied to every navigation bar in the application.

You can see the visual result on our Item 10 of Fig. 1. Sometimes, you can use appearanceWhenContainedIn: in place of appearance, when you want to provide a different customization to a UI element that is contained in a container class. For example, suppose you want every UIBarButtonItem have a red background color, except when they are added to a toolbar. In this case, you can use the appearanceWhenContainedIn: method to customize those bar button items.

Tiling and stretching images

The retina display is amazing, especially on the iPad. I really love it. However, this kind of display introduced so many technical challenges. One of them is the final application size. For example, think of a navigation bar on the new iPad (with retina display). Imagine you want to customize it with a background image. You need to prepare a 768x44 image (non-retina version) and a 1536x88 image (retina version). Sometimes, you need also to add the landscape versions of the same navigation bar, so a 1024x44 image and a 2048x88 image. So, you end up with four images just for the navigation bar.
Same rule applies to every UI element. Well, there is a way to reduce the application size.

If you are not using any special texture on the navigation bar, you can simply pass a 3x44 image for both landscape and portrait low-resolution and a 6x88 image for both the landscape and portrait high-resolution cases. How? Check the following Fig.2:


Fig. 2. UIEdgeInsets structure

You can associate to an image a UIEdgeInsets structure. As highlighted in Fig. 2, the structure contains 4 float numbers: top, left, bottom and right. Those are the portions of the image that are kept fixed during the image scaling. The intermediate portion of the image (horizontally and vertically) gets instead stretched or tiled by UIKit if you ask so.

You can do this in the following way:

The first line simply loads an image. The second line creates the edge insets. Finally, the third line resizes the input image using the previously defined edge insets. The resulting image imageRes is identical to the original image imageIn, but during scaling or resizing, areas covered by a cap are not scaled or resized. Instead, the pixel area not covered by the cap in each direction is tiled, left-to-right and top-to-bottom, to resize the image. For best performance, Apple suggests to use a tiled area that is a 1x1 pixel area in size.

What if you want to stretch instead of tiling. You can use the resizableImageWithCapInsets:resizingMode: method and pass UIImageResizingModeStretch as a second argument.

Final remarks

You will agree with me that the customization of the iOS UI has become simpler, right? You can create custom elements very easily like we’ve been doing through this tutorial.

Hope this post was useful! Thanks for reading!




(Visited 573 times, 1 visits today)