An iOS 6 iPhone UIPickerView Example

From Techotopia
Revision as of 19:01, 5 October 2012 by Neil (Talk | contribs) (New page: <table border="0" cellspacing="0" width="100%"> <tr> <td width="20%">Previous<td align="center">[[iPhone iOS 6 Development Essentials...)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search
PreviousTable of ContentsNext
Using the UIPickerView and UIDatePicker ComponentsWorking with Directories on iOS 6


<google>BUY_IOS6</google>


Unlike the UIDatePicker class, which is pre-configured by Apple specifically for date and time selection, the UIPickerView class is intended to be configured to meet the specific requirements of the iPhone application developer. Having provided a basic overview of pickers and an example of the use of the DatePicker in Using the UIPickerView and UIDatePicker Components in iOS 6 iPhone Applications, the objective of this chapter is to provide a worked example of the UIPickerView class in action.


Contents


Creating the iOS 6 PickerView Project

The example application in this chapter is a rudimentary currency conversion tool. The user will enter a US Dollar amount into a text field and then make a currency selection from a PickerView object, at which point the equivalent amount in the chosen currency will be displayed on a label.

Begin by creating a new iOS iPhone Xcode project named Picker with a corresponding class prefix using the Single View Application template with Storyboard and Automatic Reference Counting support enabled.

UIPickerView Delegate and DataSource

Before starting on the project it is worth taking some time to talk about the delegate and datasource of the UIPickerView class. In order to obtain the options to be displayed to the user, the PickerView needs a data source. This data source takes the form of a protocol that defines the methods that must be implemented in order to provide the Picker with data information. At a minimum the class designated as the data source must implement the following methods:

  • numberOfComponentsInPickerView: - Called by the PickerView to identify the number of components (i.e. selection wheels) that are to be displayed to the user.
  • numberOfRowsInComponent: - Informs the PickerView of the number of rows (in other words the selection options) that are present in a specified component.
  • titleForRow: - Called by the PickerView to identify the string that is to be displayed for a specified row in a specific component.

In addition to a data source, the PickerView also needs a mechanism for notifying the application code when a selection has been made by the user. It achieves this by calling the didSelectRow method of the class declared as the PickerView’s delegate.

In order to fully implement a PickerView, therefore, it is necessary for the object to be assigned a data source and delegate. Typically the view controller responsible for the PickerView is the best place to implement these two protocols.


The PickerViewController.h File

The first step is to implement the declarations in the PickerViewController.h file. Since we plan to make our view controller both the delegate and data source for the UIPickerView instance, the view controller must be declared as implementing both the UIPickerViewDelegate and UIPickerViewDataSource protocols.

In addition, two arrays are needed to store the country names and corresponding exchange rates:

#import <UIKit/UIKit.h>

@interface PickerViewController : UIViewController
        <UIPickerViewDelegate, UIPickerViewDataSource>

@property (strong, nonatomic) NSArray *countryNames;
@property (strong, nonatomic) NSArray *exchangeRates;
@end  

Designing the User Interface

To design the user interface, begin by selecting the MainStoryboard.storyboard file to load it into Interface Builder. Drag and drop a UIPickerView from the Object library (View -> Utilities -> Show Object Library) onto the view and position it at the bottom of the view. Also add a label and text field. Stretch the right and left hand edges of the label until the dotted blue margin line appears. Using the Attribute Inspector (View -> Utilities -> Show Attribute Inspector), configure centered alignment on the label.

Select the text field and change the Placeholder setting in the Attribute Inspector to US Dollars (USD). Once completed, the view should appear as illustrated in the following figure:


Iphone ios 6 datepicker ui.png

Figure 30-1


Select the Picker View object in the view canvas, display the Assistant Editor panel and verify that the editor is displaying the contents of the PickerViewController.h file. Ctrl-click on the Picker View object and drag to a position just below the @interface line in the Assistant Editor. Release the line and in the resulting connection dialog establish an outlet connection named picker. Repeat these steps to establish outlet connections from the Text Field and Label to properties named dollarText and resultLabel respectively.

Next, select the PickerView component in the View window and display the Connections Inspector (View -> Utilities -> Show Connections Inspector). Click in the round circle to the right of the dataSource outlet in the inspector window and drag the line to the Picker View Controller object in the document outline panel located to the left of the storyboard canvas. Repeat this task for the delegate outlet.

Finally, Ctrl-click on the text field object and drag the line to the area immediately beneath the newly created outlets in the Assistant Editor panel. Release the line and, within the connection dialog, establish an Action method on the Did End On Exit event configured to call a method named textFieldReturn.

The user interface is now designed and the outlets and action connected.

Initializing the Arrays

The data that will be used in our application is stored in two arrays, one for the country name and the other for the corresponding exchange rate. In the real world, the application would likely obtain up-to-date exchange rate information from an external source, but for the purposes of this example we will hard code the prevailing rates at the time of writing. These arrays need to be initialized when the application loads, so the necessary code should be added to the viewDidLoad method of the PickerViewController.m file:

#import "PickerViewController.h"

@interface PickerViewController ()

@end

@implementation PickerViewController
.
.
- (void)viewDidLoad {
      [super viewDidLoad];
      _countryNames = @[@"Australia (AUD)", @"China (CNY)",
              @"France (EUR)", @"Great Britain (GBP)", @"Japan (JPY)"];

      _exchangeRates = @[ @0.9922f, @6.5938f, @0.7270f, 
              @0.6206f, @81.57f];
}

Implementing the DataSource Protocol

The next step is to implement the methods that comprise the UIPickerViewDataSource protocol. Since we have declared the pickerViewController class as the data source we need to implement the methods in the pickerViewController.m file:

#pragma mark -
#pragma mark PickerView DataSource

- (NSInteger)numberOfComponentsInPickerView:
(UIPickerView *)pickerView
{
        return 1;
}

- (NSInteger)pickerView:(UIPickerView *)pickerView
      numberOfRowsInComponent:(NSInteger)component
{
        return _countryNames.count;
}

- (NSString *)pickerView:(UIPickerView *)pickerView
titleForRow:(NSInteger)row
forComponent:(NSInteger)component
{
    return _countryNames[row];
} 

The first method simply returns a value of 1 since our picker only has one component. The second method returns the number of rows in the component by counting the number of elements in the country name array. Finally, the titleForRow method returns the corresponding country name for the requested row by using the row number as a reference into the country names array.

Implementing the Delegate Protocol

For the purposes of this example, the only delegate method we need to implement is the one that gets called when the user makes a selection from the PickerView component. The code for this method also belongs in the pickerViewController.m file and should be implemented as follows:

#pragma mark -
#pragma mark PickerView Delegate
-(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row
inComponent:(NSInteger)component
{
        float rate = [_exchangeRates[row] floatValue];
        float dollars = [_dollarText.text floatValue];
        float result = dollars * rate;

        NSString *resultString = [[NSString alloc] initWithFormat:
                @"%.2f USD = %.2f %@", dollars, result,
               _countryNames[row]];
        _resultLabel.text = resultString;
}

This method takes the selected row number argument and uses it as an index to obtain the exchange rate from the exchangeRates array. Next, the dollar amount entered by the user is converted from a string to a floating point number and multiplied by the US Dollar amount to arrive at a conversion value.

Finally, a string is constructed from the dollar amount, the converted amount and the country name. This string is then displayed on the label and the string released.

Hiding the Keyboard

Since the keyboard will obscure the picker when displayed, the last task before testing the application is to make sure the keyboard is hidden when the user touches the Return key. Still within the pickerViewController.m file, therefore, implement the textFieldReturn action method as follows:

-(IBAction)textFieldReturn:(id)sender
{
    [sender resignFirstResponder];
}

Testing the Application

Once the code changes have been made and the corresponding files saved, click on the Run button located in the Xcode project window toolbar. The application should load into the iOS Simulator where a dollar amount may be entered and countries selected to obtain currency conversion values:


An example iOS 6 iPhone UIPickerView application running

Figure 30-2


<google>BUY_IOS6</google>



PreviousTable of ContentsNext
Using the UIPickerView and UIDatePicker ComponentsWorking with Directories on iOS 6