MOBILE

iPhone Application Development : Getting the User’s Attention - Using Action Sheets

2/24/2011 3:57:48 PM
Sometimes, however, a user should be prompted to make a decision based on the result of an action. For example, if an application provides the option to share information with a friend, the user might be prompted for the method of sharing (such as sending an email, uploading a file, and so on). You can see this behavior when adding a bookmark in Safari, as shown in Figure 1. This interface element is called an action sheet and is an instance of UIActionSheet.
Figure 1. An action sheet provides multiple options based on the context in which an action is being carried out.


Action sheets are also used to confirm actions that are potentially destructive to data. In fact, they provide a separate bright-red button style to help draw a user’s attention to potential deletion of data.

Displaying an Action Sheet

Action sheets are very similar to alerts in how they are initialized, modified, and, ultimately, acted upon. However, unlike alerts, an action sheet can be associated with a given view, tab bar, or toolbar. When an action sheet appears onscreen, it is animated to show its relationship to one of these elements.

To create your first action sheet, we’ll use the method stub doActionSheet created within the GettingAttentionViewController.m file. Recall that this method will be triggered by pushing the Lights, Camera, Action Sheet button. Add the code in Listing 1 to the doActionSheet method.

Listing 1.
1: - (IBAction)doActionSheet:(id)sender {
2: UIActionSheet *actionSheet;
3: actionSheet=[[UIActionSheet alloc] initWithTitle:@"Available Actions"
4: delegate:nil
5: cancelButtonTitle:@"Cancel"
6: destructiveButtonTitle:@"Destroy"
7: otherButtonTitles:@"Negotiate",@"Compromise",nil];
8: [actionSheet showInView:self.view];
9: }


Lines 2–3 declare and instantiate an instance of UIActionSheet called actionSheet. Similar to the setup of an alert, the initialization convenience method takes care of nearly all the setup. The parameters are as follows:

initWithTitle: Initializes the sheet with the specified title string.

delegate: Contains the object that will serve as the delegate to the sheet. If this is set to nil (which we will do initially), the sheet will be displayed, but pressing a button will have no effect beyond dismissing the sheet.

cancelButtonTitle: Set the string shown in the default button for the alert.

destructiveButtonTitle: The title of the option that will result in information being lost. This button will be presented in bright red (a sharp contrast to the rest of the choices). If set to nil, no destructive button will be displayed.

otherButtonTitles: Adds additional buttons to the sheet. In this example, we have a total of four buttons: the Cancel button, Destroy button, and two other buttons.

In line 8, the action sheet is displayed in the current view controller’s view (self.view) using the UIActionSheet showInView: method. Figure 2 shows the result.

Figure 2. Action sheets can include cancel and destructive buttons, as well as buttons for other options.


By the Way

Action sheets can take up to seven buttons (including Cancel and the Destroy button) while maintaining the standard layout. If you exceed seven, however, the display will automatically change into a scrolling table. This gives you room to add as many options as you need.


Changing the Action Sheet Appearance

Based on what you’ve learned so far, you might have noticed that an action sheet is more configurable than an alert view. An action sheet defines three different types of buttons with three different appearances (cancel, destructive, other). Any of the button titles can be set to nil, and that button type will not be displayed in the sheet.

By the Way

To add buttons to the action sheet outside of the initialization method, use the addButtonWithTitle: method.


You can also change how the sheet is drawn on the screen. In the example we’re creating, the showInView: method is used to animate the opening of the sheet from the current view controller’s view. If you had an instance of a toolbar or a tab bar, you could use showFromToolbar: or showFromTabBar: to make the sheet appear to open from either of these user interface elements.

Perhaps more dramatically, an action sheet can take on different appearances if you set the actionSheetStyle property. For example, try adding the following line to the doActionSheet method:

actionSheet.actionSheetStyle=UIBarStyleBlackTranslucent;

This code draws the action sheet in a translucent black style. You can also use UIActionSheetStyleAutomatic to inherit the style of the view’s toolbar (if any is set) or UIActionSheetStyleBlackOpaque for a shiny solid-black style.

Responding to an Action Sheet Button Press

As you’ve seen, there are more than a few similarities in how alert views and action sheets are set up. The similarities continue with how an action sheets reacts to a button press, for which we will follow almost the same steps as we did with an alert view.

First, we need to conform to a new protocol. Modify GettingAttentionViewController.h to include the UIActionSheetDelegate protocol:

@interface GettingAttentionViewController :
UIViewController <UIAlertViewDelegate, UIActionSheetDelegate> {
IBOutlet UILabel *userOutput;
}

Next, to capture the click event, we need to implement the actionSheet:clickedButtonAtIndex method. As with alertView:clickedButtonAtIndex:, this method provides the button index that was pressed within the action sheet. Add the code in Listing 2 to GettingAttentionViewController.m.

Listing 2.
 1: - (void)actionSheet:(UIActionSheet *)actionSheet
2: clickedButtonAtIndex:(NSInteger)buttonIndex {
3: NSString *buttonTitle=[actionSheet buttonTitleAtIndex:buttonIndex];
4: if ([buttonTitle isEqualToString:@"Destroy"]) {
5: userOutput.text=@"Clicked 'Destroy'";
6: } else if ([buttonTitle isEqualToString:@"Negotiate"]) {
7: userOutput.text=@"Clicked 'Negotiate'";
8: } else if ([buttonTitle isEqualToString:@"Compromise"]) {
9: userOutput.text=@"Clicked 'Compromise'";
10: } else {
11: userOutput.text=@"Clicked 'Cancel'";
12: }
13: }

Now we can use buttonTitleAtIndex (line 3) to get the titles used for the buttons based on the index provided. The rest of the code follows exactly the same pattern created earlier. Lines 4–12 test for the different button titles and update the view’s output message to indicate what was chosen.

An Alternative Approach

Once again, we’ve chosen to match button presses based on the title of the onscreen button. If you’re adding buttons dynamically, however, this might not be the best approach. The addButtonWithTitle method, for example, adds a button and returns the index of the button that was added. Similarly, the cancelButtonIndex and destructiveButtonIndex methods provide the indexes for the two specialized action sheet buttons.

By checking against these index values, you can write a version of the actionSheet:clickedButtonAtIndex: method that is not dependent on the title strings. The approach you take in your own applications should be based on what creates the most efficient and easy-to-maintain code.


Other  
  •  jQuery 1.3 : Modifying table appearance (part 4) - Filtering
  •  jQuery 1.3 : Modifying table appearance (part 3) - Collapsing and expanding sections
  •  jQuery 1.3 : Modifying table appearance (part 2) - Tooltips
  •  jQuery 1.3 : Modifying table appearance (part 1) - Row highlighting
  •  Windows Phone 7 Development : Using Culture Settings with ToString to Display Dates, Times, and Text
  •  Mobile Application Security : SymbianOS Security - Persistent Data Storage
  •  Mobile Application Security : SymbianOS Security - Interprocess Communication
  •  Mobile Application Security : SymbianOS Security - Permissions and User Controls
  •  Windows Phone 7 Development : Building a Trial Application (part 3) - Verifying Trial and Full Mode & Adding Finishing Touches
  •  Windows Phone 7 Development : Building a Trial Application (part 2) - Connecting to a Web Service & Adding Page-to-Page Navigation
  •  Windows Phone 7 Development : Building a Trial Application (part 1) - Building the User Interface
  •  jQuery 1.3 : Table Manipulation - Sorting and paging (part 2) : Server-side pagination & JavaScript pagination
  •  jQuery 1.3 : Table Manipulation - Sorting and paging (part 1) : Server-side sorting & JavaScript sorting
  •  Windows Phone 7 Development : Understanding Trial and Full Modes (part 3) - Simulating Application Trial and Full Modes
  •  Windows Phone 7 Development : Understanding Trial and Full Modes (part 2) - Using the Marketplace APIs
  •  Windows Phone 7 Development : Understanding Trial and Full Modes (part 1) - Using the IsTrial Method
  •  Mobile Application Security : SymbianOS Security - Application Packaging
  •  Mobile Application Security : SymbianOS Security - Code Security
  •  iPhone Application Development : Getting the User’s Attention - Generating Alerts
  •  iPhone Application Development : Getting the User’s Attention - Exploring User Alert Methods
  •  
    Top 10
    SQL Server 2008 : Common performance problems (part 2)
    SQL Server 2008 : Common performance problems (part 1) - Procedure cache bloating
    SQL Server 2008 : SQLOS schedulers, Wait analysis
    Windows Server 2003 : Recovering from System Failure
    Windows Server 2003 : Advanced Backup and Restore (part 2) - Scheduling Backup Jobs, Shadow Copies of Shared Folders
    Windows Server 2003 : Advanced Backup and Restore (part 1) - Managing Media, Backup Options, The Ntbackup Command
    Windows Server 2003 : Managing and Implementing Disaster Recovery - Restoring Data
    Microsoft .NET : Design Principles and Patterns - From Objects to Aspects (part 2) - AOP in Action
    Microsoft .NET : Design Principles and Patterns - From Objects to Aspects (part 1) - Aspect-Oriented Programming
    ASP.NET 4 in VB 2010 : The Data Controls - Editing with the GridView
    Most View
    Systems for All Budgets (Part 3) - WS 1000, Silent 1000
    Windows Phone 7 Development : Using a WebBrowser Control to Display Web Content
    How Secure Is Your Pin? (Part 2)
    MySQL for Python : Creating Users and Granting Access - GRANT access in MySQL
    Low- Pass Filter Removal (Part 3)
    Exchange Server 2007: Recover a Non-Mailbox Role
    Collaborating Within an Exchange Server Environment Using Microsoft Office SharePoint Server 2007 : Understanding the History of SharePoint Technologies
    Nokia 808 PureView – It Is All About The Photos
    ASP.NET State Management Techniques : The Role of the Global.asax File
    Group Test: Web Browsers (Part 3) : Safari 5.1.7
    G.skill ARES DDR3 2133MHz 8GB Kit
    Undelete 10 - Fairly Easy To Use
    Custom: Installation Nation (Part 2)
    Silverlight Recipes : Managing XAML Resources
    300 Lumen LED Flash For iPhone
    Onyx Calypso 9.7 Tablet
    Windows Server 2003 : Protecting Network Communications with Internet Protocol Security - IPSec Basics (part 2) - Differences Between AH and ESP, Process and Procedure
    Exchange Server 2010 Coexistence : Coexistence with Exchange Server 2003
    Nokia Lumia 900 - The Brightest Star In Lumia Series
    Canon IXUS 500 HS - Small-But-Mighty Premium Compact