iPhone Application Development : Implementing a Custom Picker View (part 3) - Reacting to a Picker View Choice

2/27/2011 10:20:25 AM

Reacting to a Picker View Choice

For our application to respond to a user touching and changing the value within one of the picker components, we need to implement another method within the UIPickerViewDelegate protocol: pickerView:didSelectRow:inComponent. This method is called when the user changes something in the picker view—as part of the parameters, we get back a reference to the picker itself, the row number that was selected, and which component number it was in.

Do you see any problem with that? Although the method certainly tells us when something was picked, and what was picked, it only gives us the value for the picker component that the user was changing. In other words, we’ll get back the chosen animal name but not the sound (or vice versa).

To access the value of any picker component at any time, we can use the UIPickerView instance method selectedRowInComponent. This returns the currently selected row in whatever component number we pass to it. If we have a reference to our picker in pickerView, for example, we could retrieve the selected animal name row like this:

[pickerView selectedRowInComponent:animalComponent]

By the Way

Hopefully it’s starting to become obvious why it makes sense to use constants to keep track of the component numbers. Being able to use animalComponent or soundComponent directly in the code makes it much easier to read, and, long term, easier to maintain.

With all this information in hand, we’re ready to write and review the pickerView:didSelectRow:inComponent method. Add the code in Listing 6 into MatchPickerViewController.m.

Listing 6.
 1: - (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row
2: inComponent:(NSInteger)component {
3: NSString *actionMessage;
4: NSString *matchMessage;
5: int selectedAnimal;
6: int selectedSound;
7: int matchedSound;
9: if (component==animalComponent) {
10: actionMessage=[[NSString alloc]
11: initWithFormat:@"You selected the animal named '%@'",
12: [animalNames objectAtIndex:row]];
13: } else {
14: actionMessage=[[NSString alloc]
15: initWithFormat:@"You selected the animal sound '%@'",
16: [animalSounds objectAtIndex:row]];
17: }
19: selectedAnimal=[pickerView selectedRowInComponent:animalComponent];
20: selectedSound=[pickerView selectedRowInComponent:soundComponent];
22: matchedSound=([animalSounds count]-1)-
23: [pickerView selectedRowInComponent:soundComponent];
25: if (selectedAnimal==matchedSound) {
26: matchMessage=[[NSString alloc] initWithFormat:@"Yes, a %@ does go '%@'!",
27: [animalNames objectAtIndex:selectedAnimal],
28: [animalSounds objectAtIndex:selectedSound]];
29: } else {
30: matchMessage=[[NSString alloc] initWithFormat:@"No, a %@ doesn't go '%@'!",
31: [animalNames objectAtIndex:selectedAnimal],
32: [animalSounds objectAtIndex:selectedSound]];
33: }
35: lastAction.text=actionMessage;
36: matchResult.text=matchMessage;
38: [matchMessage release];
39: [actionMessage release];
41: }

Lines 3–4 kick off the implementation by declaring two strings, actionMessage and matchMessage, which will be used to hold the contents of the messages that we’ll be displaying to the user to view the labels in the interface.

Lines 5–7 define three integers (selectedAnimal, selectedSound, and matchedSound) that we’ll be using to hold the currently selected animal and sound and the “fixed” number of the currently selected sound. Recall that the sound and animal rows don’t match up numerically? We’ll use the matchSound variable to hold the results of the calculation that determines whether the sound the user has chosen matches the correct animal.

Lines 9–17 allocate and initialize a string, actionMessage, which describes what the user has done. If the component provided to the method is the animalComponent, the string will contain a message stating that they chose an animal. It will also identify the animal via the row variable and the animalNames array. If they choose a sound, the message and logic will be appropriate to that action instead. We’re using the same techniques implemented earlier to populate the picker’s display.

Lines 19–20 use the selectedRowInComponent method to retrieve the currently selected rows in the animal and sound components. The results are stored in the selectedAnimal and selectedSound variables, respectively.

Lines 22–23 work the magic of calculating if the chosen sound matches the chosen animal. The matchedSound value will equal the selectedAnimal value if the user has picked a match. You can refer to the earlier section “Populating the Data Structures” for help understanding the math—it isn’t critical in understanding the picker view itself.

Lines 25–33 compare selectedAnimal to matchedSound. If they are equal, the user has chosen correctly, and an appropriately congratulatory message is created and stored in the string matchMessage. If users make an incorrect choice, they’re informed of the error with a slightly different message. In either case, the matchMessage string includes both the name of the animal and the sound so that users complete feedback about what they’ve selected.

Lines 35–36 output the actionMessage and matchMessage to the user by setting the text properties of the lastAction and matchResult labels.

Lines 38–39 release the two strings, matchMessage and actionMessage, allocated and initialized in the method.

Save your updated implementation file, and choose Build and Run. Scroll through the animals and sounds and make your choices. As you change the selection in the picker view, the messages should update accordingly, as Figure 7 shows.

Figure 7. Your application now reacts to changes in the picker view!

Done? Not just yet! When we started out, I promised that we’d be able to display images in the picker view, and I’m not going to go back on my word!

  •  Windows Phone 7 Development : Isolated Storage - Working with Isolated Storage Settings
  •  Mobile Application Security : WebOS Security - Permissions and User Controls
  •  Mobile Application Security : WebOS Security - Code Security
  •  Windows Phone 7 Development : Working with Isolated Directory Storage (part 2)
  •  Windows Phone 7 Development : Working with Isolated Directory Storage (part 1)
  •  iPhone Application Development : Making Multivalue Choices with Pickers - Using Date Pickers (part 3)
  •  iPhone Application Development : Making Multivalue Choices with Pickers - Using Date Pickers (part 2) - Adding a Date Picker
  •  iPhone Application Development : Making Multivalue Choices with Pickers - Using Date Pickers (part 1)
  •  iPhone Application Development : Making Multivalue Choices with Pickers - Understanding Pickers
  •  Sync Your iPad with iTunes : Troubleshooting iTunes and the Sync
  •  Sync Your iPad with iTunes : Manually Transferring Music, Movies, Podcasts, and More on Your iPad (Drag-and-Drop Method)
  •  Windows Phone 7 Development : Internationalization - Using Resource Files to Localize Content
  •  Windows Phone 7 Development : Internationalization - Storing and Retrieving Current Culture Settings
  •  Mobile Application Security : WebOS Security - Development and Security Testing
  •  Mobile Application Security : WebOS Security - Introduction to the Platform
  •  iPhone Application Development : Getting the User’s Attention - Using Alert Sounds and Vibrations
  •  iPhone Application Development : Getting the User’s Attention - Using Action Sheets
  •  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
    Top 10
    Primer – Choosing And Using Peripheral Buses (Part 2)
    Primer – Choosing And Using Peripheral Buses (Part 1)
    SanDisk ReadyCache 32GB - Caching Solution SSD
    Windows 8 Tips And Tricks – Jan 2013
    Lenovo IdeaPad S400 - Stylish And Affordable Laptop
    Nokia Lumia 920 - Super Smart, Super-Size Handset
    Optimus L9 - The Nicest Phone In LG's 'L' Line
    Bits Of Bytes
    Happy iMas (Part 2)
    Happy iMas (Part 1)
    Most View
    Designing and Configuring Unified Messaging in Exchange Server 2010 : Unified Messaging Architecture (part 3)
    Use a Stopwatch to Profile Your Code
    Synchronizing Mobile Data - Using Merge Replication (part 2) - Programming for Merge Replication
    # BlackBerry Java Application Development : Networking - HTTP Basics
    iPhone 3D Programming : Vector Beautification with C++
    Capacity Efficiency - Create Sustainable Storage and Mitigate Rising Costs
    Memory Management : Force a Garbage Collection, Create a Cache That Still Allows Garbage Collection
    Enhance Images with iPhoto on iPad
    Windows 7 : Zero Touch Installations - Understanding Configuration Manager
    Windows Phone 7 Development : Debugging Application Exceptions (part 2) - Debugging a Web Service Exception
    Richard Cobbett: Publish and be damned
    The SQL Programming Language : Creating Tables and Entering Data
    System Builder - The Future Of USB
    Low- Pass Filter Removal (Part 1)
    Silverlight Recipes : Save a File Anywhere on the User's System
    Aquacomputer Airplex XT 240
    Windows Server 2008 and Windows Vista : Working with GPOs - Group Policy Results
    Exchange Server 2007: Administrate Transport Settings - Work with Accepted Domains
    CMS Revolution (Part 1)
    Windows Server 2003 : Active Directory Troubleshooting and Maintenance