An iOS 7 UIPickerView Example

From Techotopia
Jump to: navigation, search
PreviousTable of ContentsNext
Using the iOS 7 UIPickerView and UIDatePicker ComponentsWorking with Directories on iOS 7


Learn SwiftUI and take your iOS Development to the Next Level
SwiftUI Essentials – iOS 16 Edition book is now available in Print ($39.99) and eBook ($29.99) editions. Learn more...

Buy Print Preview Book


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 iOS application developer. Having provided a basic overview of pickers and an example of the use of the DatePicker in Using the iOS 7 UIPickerView and UIDatePicker Components, the objective of this chapter is to provide a worked example of the UIPickerView class in action.


Contents


Creating the iOS 7 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 Xcode project named Picker with a corresponding class prefix using the Single View Application template for the iPhone device family.

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 Main.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 Attributes Inspector (View -> Utilities -> Show Attributes Inspector), configure centered alignment on the label and reduce the font size to 12 point.

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

The user interface layout for an iOS 7 UIPickerView example app

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 icon located in the panel beneath the view canvas (Figure 30-2). Repeat this task for the delegate outlet.


Connecting a datasource outlet in Xcode 5

Figure 30-2


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];
}

Learn SwiftUI and take your iOS Development to the Next Level
SwiftUI Essentials – iOS 16 Edition book is now available in Print ($39.99) and eBook ($29.99) editions. Learn more...

Buy Print Preview Book

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.

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 iOS 7 UIPickerView example running

Figure 30-3


Learn SwiftUI and take your iOS Development to the Next Level
SwiftUI Essentials – iOS 16 Edition book is now available in Print ($39.99) and eBook ($29.99) editions. Learn more...

Buy Print Preview Book


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