MOBILE

iPhone Application Development : Working with Text, Keyboards, and Buttons (part 3) - Creating Styled Buttons

1/16/2011 3:45:30 PM

Creating Styled Buttons

Working with buttons is relatively straightforward, but what you may have noticed is that, by default, the buttons you create in Interface Builder are, well, kind of boring.

We need a single button in this project, so drag an instance of the Rounded Rect button (UIButton) from the Objects Library to the bottom of the view. Title the button Generate Story. The final view, with a default button, can be seen in Figure 11.

Figure 11. The default button styles are less than appealing.


Although you’re certainly welcome to use the standard buttons, you may want to explore what visual changes you can make in Interface Builder and ultimately through code changes.

Editing Button Attributes

To edit a button’s appearance, your first stop is, once again, the Attributes Inspector (Command+1). Using the Attributes Inspector, you can dramatically change the appearance of the button. Use the Type drop-down menu, shown in Figure 12, to choose common button types:

Rounded Rect: The default iPhone button style.

Detail Disclosure: An arrow button used to indicate additional information is available.

Info Light: An “i” icon, typically used to display additional information about an application or item. The “Light” version is intended for dark backgrounds.

Info Dark: The dark (light background) version of the Info Light button.

Add Contact: A + button, frequently used to indicate the addition of a contact to the address book.

Custom: A button that has no default appearance. Usually used with button images.

Figure 12. The Attributes Inspector gives several options for common button types, as well as a custom option.


In addition to choosing a button type, you can make the button interact with user touches, a concept known as changing state. For instance, by “default,” a button is displayed unhighlighted within the view. When a user touches a button, it changes to a highlighted “on” state, showing that it has been touched.

Using the Attributes Inspector, you can use the State Configuration menu to change the button’s title, background color, or even add a graphic image.

Setting Custom Button Images

To create custom iPhone buttons, you’ll need to make custom images, including versions for the highlighted on state and the default off state. These can be any shape or size, but PNG format is recommended because of its compression and transparency features.

After you’ve added these to the project through Xcode, you’ll be able to select the image from the Image or Background drop-down menus in Interface Builder’s button attributes. Using the Image menu sets an image that appears inside the button alongside the button title. This option enables you to decorate a button with an icon.

Using the Background menu sets an image that will be stretched to fill the entire background of the button. The option lets you create a custom image as the entire button, but you’ll need to size your button exactly to match the image. If you don’t, the image will be stretched and pixilated in your interface.

Another way to use custom button images that will correctly size to your text is through the code. We’ll apply this technique to our project now.

Remember how we created an outlet for a button earlier in the project? We need the outlet so that we can manipulate the button in Xcode. Control-drag from the File’s Owner icon in the Document window in Interface Builder to the Generate Story button. Pick the generateStory outlet when prompted, as demonstrated in Figure 13.

Figure 13. We need to access the button properties from our application to manipulate its images.


Now, switch your attention to Xcode. Inside the FieldButtonFun directory is an Images folder with two Apple-created button templates: whiteButton.png and blueButton.png. Drag these image files into the Resources folder in Xcode, choosing to copy the resources, if necessary, as shown in Figure 14.

Figure 14. To use custom buttons, drag them into the Resources folder in Xcode, and choose to copy the resources if needed.

Within Xcode, open the FieldButtonFunViewController.m file and search for the method viewDidLoad, uncomment it by removing the /* */ comment markers that surround it.

Implement the viewDidLoad method using the code in Listing 2.

Listing 2.
 1: -(void)viewDidLoad {
2: UIImage *normalImage = [[UIImage imageNamed:@"whiteButton.png"]
3: stretchableImageWithLeftCapWidth:12.0
4: topCapHeight:0.0];
5: [generateStory setBackgroundImage:normalImage forState:UIControlStateNormal];
6: UIImage *pressedImage = [[UIImage imageNamed:@"blueButton.png"]
7: stretchableImageWithLeftCapWidth:12.0
8: topCapHeight:0.0];
9: [generateStory setBackgroundImage:pressedImage
10: forState:UIControlStateHighlighted];
11:
12: [super viewDidLoad];
13: }


In this code block, we’re accomplishing several different things, all focused on providing the button instance (generateStory) with a reference to an image object (UIImage) that “knows” how it can be stretched.

Did you Know?

Why are we implementing this code in the viewDidLoad method? Because it is automatically invoked after the view is successfully instantiated from the XIB file. This gives us a convenient hook for making changes (in this case, adding button graphics) right as the view is being displayed onscreen.


In lines 2–4 and 6–8, we first return an instance of an image from the image files that we added to the project resources. Then we define that image as being stretchable. Let’s break this down into the individual statements:

To create an instance of an image based on a named resource, we use the UIImage class method imagenamed, along with a string that contains the filename of the image resource. For example, this code fragment creates an instance of the whiteButton.png image:

[UIImage imageNamed:@"whiteButton.png"]

Next, we use the instance method stretchableImageWithLeftCapWidth:topCapHeight to return another new instance of the image, but this time with properties that define how it can be stretched. These properties are the left cap width and top cap width, which describe how many pixels in from the left or down from the top of the image should be ignored before reaching a 1-pixel-wide strip that can be stretched. For instance, if the left cap is set to 12, a vertical column 12 pixels wide is ignored during stretching, and then the 13th column is repeated however many times is necessary to stretch to the requested length. The top cap works the same way but repeats a horizontal row to grow the image to the correct size vertically, as illustrated in Figure 15. If the left cap is set to zero, the image can’t be stretched horizontally. Similarly, if the top cap is zero, the image can’t be stretched vertically.

Figure 15. The caps define where within an image stretching can occur.


In this example, we use stretchableImageWithLeftCapWidth:12.0 topCapHeight:0.0 to force horizontal stretching to occur at the 13th vertical column of pixels in and to disable any vertical stretching. The UIImage instance returned is then assigned to the normalImage and pressedImage variables, corresponding to the default and highlighted button states.

Lines 5 and 9–10 use the setBackgroundImage:forState instance method of our UIButton object (generateStory) to set the stretchable images normalImage and pressedImage as the backgrounds for the predefined button states of UIControlStateNormal (default) and UIControlStateHighlighted (highlighted).

This might seem a bit confusing, and I empathize. Apple has not provided these same features directly in Interface Builder, despite their usefulness in almost any application with buttons. The good news is that there is no reason that you can’t reuse this same code repeatedly in your applications.

Within Xcode, click Build and Run to compile and run your application. The Generate Story button should take on a new appearance (see Figure 16).

Figure 16. The end result is a shiny new button in the application.

Remember that despite all of our efforts to make a pretty button, we still haven’t connected it to an action. Switch back to Interface Builder to make the connection.

Connecting to the Action

To connect the button to the previously declared createStory action method, select the button object and open the Connections Inspector (Command+3) or choose Tools, Connections Inspector. Drag from the circle beside Touch Up Inside to the File’s Owner icon in the Interface Builder Document window.

When prompted for a method, choose createStory. The Connections Inspector should update, showing both the outlet that references the button (generateStory) and the createStory method, similar to Figure 17.

Figure 17. The button should now be connected to an outlet and an action.

At long last, our button is done!

Other  
  •  Building Android Apps : Controlling the Phone with JavaScript (part 3) - Accelerometer
  •  Building Android Apps : Controlling the Phone with JavaScript (part 2) - Geolocation
  •  Building Android Apps : Controlling the Phone with JavaScript (part 1) - Beep, Vibrate, and Alert
  •  Building Your First Windows Phone 7 Application (part 5) - Styling Your Application
  •  Building Your First Windows Phone 7 Application (part 4) - Customizing Your First Windows Phone Application
  •  Building Your First Windows Phone 7 Application (part 3) - Writing Your First Windows Phone Code
  •  Building Your First Windows Phone 7 Application (part 2) - Using Your First Windows Phone Silverlight Controls
  •  Building Your First Windows Phone 7 Application (part 1) - Creating a Windows Phone Project
  •  Introducing Windows Phone 7 and the Windows Phone Platform
  •  Windows Phone Application Platform
  •  iPhone Application Development : Basic User Input and Output
  •  Mobile Phone Game Programming : A Quick J2ME Primer
  •  Mobile Phone Game Programming : Java As a Mobile Game Platform
  •  Mobile Phone Game Programming : Getting to Know Mobile Platforms
  •  Mobile Application Security : The Apple iPhone - Local Data Storage: Files, Permissions, and Encryption
  •  Mobile Application Security : The Apple iPhone - Permissions and User Controls
  •  iPhone Application Developmen : Using the View-Based Application Template (part 3)
  •  iPhone Application Developmen : Using the View-Based Application Template (part 2) - Preparing the View Controller Outlets and Actions
  •  iPhone Application Developmen : Using the View-Based Application Template (part 1)
  •  Mobile Application Security: Application Format
  •  
    Most View
    Razer Taipan - Shape And Size Make It Awkward
    Windows 7 : Networking and HomeGroup Sharing - Sharing Between PCs (part 1) - HomeGroup Sharing
    Edifier E10 Exclaim - Exclamation Mark
    Retina iPad - Largely Unchanged From The ‘new iPad’ (Part 2)
    Brother DCP-7055W - Budget-Priced Laser Printer
    The Anti - iPad Assembly (Part 2) - Toshiba AT300-101, Asus Transformer Pad Infinity, Archos 101 XS Gen 10
    HTC Windows Phone 8X - The Best-Looking Windows Phone 8 Handset (Part 2)
    Nintendo WII U - Modern HD Gaming Console (Part 4)
    Most Favorite Miscellaneous Apps For Your Smartphone – November 2012 (Part 2)
    Lenovo IdeaPad Z580 - Cracking Budget Laptop
    Top 10
    G.Skill DDR3 SDRAM 32GB Review (Part 6)
    G.Skill DDR3 SDRAM 32GB Review (Part 5)
    G.Skill DDR3 SDRAM 32GB Review (Part 4)
    G.Skill DDR3 SDRAM 32GB Review (Part 3)
    G.Skill DDR3 SDRAM 32GB Review (Part 2)
    G.Skill DDR3 SDRAM 32GB Review (Part 1)
    Macbook Pro With 13in Retina Display Review (Part 3)
    Macbook Pro With 13in Retina Display Review (Part 2)
    Macbook Pro With 13in Retina Display Review (Part 1)
    Kensington Folio Trio For iPad