• USA : +1 973 910 5725
  • INDIA: +91 905 291 3388
  • info@tekslate.com
  • Login

Picker View Processing

UIPickerView

A UIPickerView allows the selection of one or more value sets. A UIPickerView consists of rows and components. Think of the component as the column and the row as the row. So ifyou had a three-wheel UIPickerView, the third wheel is the third component. A UIPickerView must have an associated class that adopts the UIPickerViewDelegate and a class that adopts the UIPickerViewDataSource. The same class can adopt both protocols.

 

UIPickerViewDelegate

The UIPickerViewDelegate protocol dictates how a UIPickerView is to construct itself. This protocol contains five methods a class might implement when adopting this protocol: the pickerView:rowHeightForComponent:, pickerView:widthForComponent:, pickerView :titleForRow:forComponent:, pickerView:viewForRow:forComponent:reusingView, and pickerView:didSelectRow:inComponent: methods.

Width and Height The pickerView:rowHeightForComponent: and pickerView:widthFor Component: methods set a picker’s component dimensions. Remember, a picker’s component can contain rows of strings or view controls, like a UIImageView. These methods accommodate controls by allowing you to set a component’s height and width. Each method’s signature follows.

  • (CGFloat)pickerView:(UIPickerView *) pickerView rowHeightForComponent:

(NSInteger) component

  • (CGFloat)pickerView:(UIPickerView *) pickerView widthForComponent:

(NSInteger) component

 

Content The pickerView:titleForRow:forComponent: and pickerView:viewForRow:for Component: methods provide a component’s title or view. The title or the view is what is displayed as the rows in a picker. You must implement one of the two methods. If using a string, implement the pickerView:titleForRow:forComponent: method; if using a view, implement the pickerView:viewForRow:forComponent: method. Each method’s signature follows.(NSString *)pickerView:(UIPickerView *)pickerView titleForRow:

(NSInteger) row forComponent: (NSInteger) component(UIView *)pickerView:(UIPickerView *)pickerView viewForRow:

(NSInteger) row forComponent:(NSInteger)component reusingView:

(UIView *)view

Selecting The UIPickerView calls the pickerView:didSelectRow:inComponent: method when a user selects a component’s row. It takes the component’s index number and the row’s index number as parameters, so you can determine the component selected and the component’s row. The method’s signature follows.(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component

UIPickerViewDatasource

 

A UIPickerViewDatasource handles a UIPickerView’s data. It contains two methods you should define when adopting this protocol: the numberOfComponentsInPickerView: and pickerView:numberOfRowsInComponent: methods. The numberOfComponentsInPickerView: method returns how many components, or columns, a picker must display.(NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent: (NSInteger) component

The pickerView:numberOfRowsInComponent: method returns a component’s row count.(NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent: (NSInteger) component

Using a Picker

  1. Create a new View-based Application named A Picker.
  2. Open xib in Interface Builder.
  3. Drag a picker view from the library to the canvas. Right-click and notice that the control doesn’t have the choices a UIDatePicker has (Figure 13-10).

 

 

 Slide130

 

                              Figure 13-10 A UIPickerView has less outlets and actions than a UIDatePicker

 

  1. Add a button to the canvas.
  2. Save and exit Interface Builder.
  3. Create a new NSObject named MyPickerDelegate and change it to adopt the UIPickerViewDelegate and UIPickerViewDataSource Have MyPickerDelegate implement the needed methods (Listings 13-7 and 13-8).
  4. Open APickerViewController and add IBOutlets for UIPickerView and MyPickerDelegate (Listing 13-9). Add an IBAction called
  5. Implement the changeColor action (Listing 13-10).
  6. Save and Open APickerViewController.xib in Interface Builder.
  7. Connect File’s Owner changeColor action to the button’s Touch Up Inside
  8. Connect File’s Owner myPicker outlet to the
  9. Drag an object from the library to the document Change the object’s type to MyPickerDelegate.
  10. Connect the File’s Owner myPickerDelegate outlet to the object just added.
  11. Connect the UIPickerView’s dataSource and delegate outlets to the newly added

 

 

 Slide131

 

Figure 13-11 Running the application in iPhone Simulator

  1. Save and exit Interface Builder.
  2. Click Build And Go to run the application in iPhone Upon pushing the button, the debugger console logs the picker’s chosen color (Figure 13-11 and Listing 13-11).

Listing 13-7 MyPickerDelegate.h

#import <Foundation/Foundation.h>

@interface MyPickerDelegate : NSObject <UIPickerViewDelegate, UIPickerViewDataSource> {

 

NSArray * myData;

}

@property (nonatomic, retain) NSArray * myData;

@end

Listing 13-8 MyPickerDelegate.m

#import “MyPickerDelegate.h”

@implementation MyPickerDelegate

@synthesize myData;

– (id) init {

if([super init] == nil) return nil; myData = [[NSArray alloc]

initWithObjects:@”Red”,@”Yellow”,@”Green”,@”Blue”, @”Purple”, @”Orange”,

@”Black”, @”Gray”, @”Tan”, @”Pink”, @”Coral”, nil]; return self;

}

  • (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {

NSLog(@”picked row: %i, component: %i”, row, component); NSLog(@”the value: %@”, [self.myData objectAtIndex:row]);

}

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

}(NSInteger) pickerView: (UIPickerView *) pickerView numberOfRowsInComponent: (NSInteger) component { return [self.myData count];

}(NSString *) pickerView: (UIPickerView *) pickerView titleForRow: (NSInteger) row forComponent: (NSInteger) component {

return [self.myData objectAtIndex:row];

}(void)dealloc { [myData release];

[super dealloc];

} @end

Listing 13-9 APickerViewController.h

#import <UIKit/UIKit.h>

#import “MyPickerDelegate.h”

@interface APickerViewController : UIViewController { IBOutlet UIPickerView * myPicker;

IBOutlet MyPickerDelegate * myPickerDelegate;

}

@property (nonatomic, retain) IBOutlet UIPickerView * myPicker;

@property (nonatomic, retain) IBOutlet MyPickerDelegate * myPickerDelegate;

– (IBAction) changeColor: (id) sender;

@end

Listing 13-10 APickerViewController.m

#import “APickerViewController.h”

@implementation APickerViewController

@synthesize myPicker;

@synthesize myPickerDelegate;

NSLog(@”the color is: %@”, (NSString *)[myPickerDelegate.myData

objectAtIndex: [myPicker selectedRowInComponent:0]]);

}(void)dealloc { [myPickerDelegate release];

[myPicker release];

[super dealloc];

} @end

Listing 13-11 Debug console output from running APicker application

[Session started at 2009-02-06 22:57:09 -0500.]

2009-02-06 22:57:13.007 APicker[429:20b] picked row: 1, component: 0

2009-02-06 22:57:13.008 APicker[429:20b] the value: Yellow

2009-02-06 22:57:14.687 APicker[429:20b] picked row: 3, component: 0

2009-02-06 22:57:14.687 APicker[429:20b] the value: Blue

2009-02-06 22:57:16.540 APicker[429:20b] picked row: 8, component: 0

2009-02-06 22:57:16.541 APicker[429:20b] the value: Tan 2009-02-06 22:57:17.499 APicker[429:20b] the color is: Tan

2009-02-06 22:57:21.215 APicker[429:20b] picked row: 10, component: 0

2009-02-06 22:57:21.215 APicker[429:20b] the value: Coral 2009-02-06 22:57:22.547 APicker[429:20b] the color is: Coral

 

A UIPickerView must have helper classes adopting the UIPickerViewDelegate and UIPickerViewDataSource protocols. In this example, you had one class, MyPickerDelegate, adopt both protocols. The delegate uses a simple NSArray to hold NSString objects. Because the data is simple strings, the delegate implements the titleForRow method. When a user selects a row, the didSelectRow method logs the row, component, and value to the debugger console.

  1. Open APicker application in Xcode.
  2. Modify MyPickerDelegate’s numberOfComponentsInPickerView to return the number 2 (Listing 13-13).
  3. Click Build And Notice the picker now shows two independent spinning wheels (Figure 13-12).
  4. Add a second value Call the array myData2 and initialize it in the init method, as you did before with myData (Listings 13-12 and 13-13).
  5. Create two constants representing the different wheels: COLOR_WHEEL for the wheel containing the myData values and SHADE_WHEEL for the wheel containing the myData2 Remember, you define constants in a class’s header file (Listing 13-12).
  6. Modify the numberOfRowsInComponent method and titleForRow method to reflect the newly added
  7. Open m and modify the changeColor method to reflect the second wheel (Listing 13-14).

 

Figure 13-12 A UIPickerView with two components

 

Slide131Slide132

 

Figure 13-13 Running the application in iPhone Simulator

 

  1. Click Build And The application shows two wheels. Upon clicking the button, the debugger console logs the first wheel’s color and the second wheel’s shade (Figure 13-13 and Listing 13-15). Listing 13-12 MyPickerDelegate.h modified to reflect two wheels

#import <Foundation/Foundation.h>

#define COLOR_WHEEL 0

#define SHADE_WHEEL 1

@interface MyPickerDelegate : NSObject <UIPickerViewDelegate,

 

UIPickerViewDataSource> {

 

NSArray * myData; NSArray * myData2;

}

@property (nonatomic, retain) NSArray * myData;

@property (nonatomic, retain) NSArray * myData2;

@end

Listing 13-13 MyPickerDelegate.m modified to reflect two wheels

#import “MyPickerDelegate.h”

@implementation MyPickerDelegate

@synthesize myData;

@synthesize myData2;

– (id) init {

if([super init] == nil) return nil;

myData = [[NSArray alloc]initWithObjects: @”Red”, @”Yellow”, @”Green”,

@”Blue”,

@”Purple”, @”Orange”, @”Black”, @”Gray”, @”Tan”, @”Pink”, @”Coral”, nil]; myData2 = [[NSArray alloc] initWithObjects: @”Very Dark”, @”Dark”, @”Normal”,

@”Light”, @”Very Light”, nil]; return self;

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

}(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {

NSLog(@”picked row: %i, component: %i”, row, component); if(component == COLOR_WHEEL)

NSLog(@”the value: %@”, [self.myData objectAtIndex:row]); else

NSLog(@”the value: %@”, [self.myData2 objectAtIndex:row]);

}

– (NSInteger) pickerView: (UIPickerView *) pickerView numberOfRowsInComponent: (NSInteger) component {

if(component == COLOR_WHEEL) return [self.myData count];

else

return [self.myData2 count];

}

– (NSString *) pickerView: (UIPickerView *) pickerView titleForRow: (NSInteger) row forComponent: (NSInteger) component {

if(component == COLOR_WHEEL) return [self.myData objectAtIndex:row]; else

return [self.myData2 objectAtIndex:row];

}

– (void)dealloc { [myData release]; [myData2 release];

[super dealloc];

} @end

 

Listing 13-14 The changeColor method modified to reflect two wheels

– (IBAction) changeColor: (id) sender {

NSLog(@”the color is: %@ and the shade is: %@”, (NSString *) [myPickerDelegate.myData objectAtIndex: [myPicker selectedRowInComponent: COLOR_WHEEL]], (NSString *)[myPickerDelegate

.myData2 objectAtIndex: [myPicker selectedRowInComponent:SHADE_ WHEEL]]);

}

Listing 13-15 Debugger console logging from running APicker application [Session started at 2009-02-06 23:01:29 -0500.]

2009-02-06 23:01:32.630 APicker[550:20b] picked row: 7, component: 0

2009-02-06 23:01:38.632 APicker[550:20b] the value: Orange

— snip —

2009-02-06 23:01:39.508 APicker[550:20b] the color is: Orange and the shade is: Very Light

Using more components involves adding code to check which component was selected. But note, rather than using the raw integers, in this task, you created constants for both components. Each delegate’s method then checks which component the user selected.

if(component == COLOR_WHEEL) return [self.myData objectAtIndex:row]; else

return [self.myData2 objectAtIndex:row];

 

Loading UIImageViews into a UIPickerView

  1. Open the APicker application created earlier—not the project with two components, but the earlier project with only one component.
  1. Replace the pickerView:titleForRow:forComponent: method in MyPickerDelegate with pickerView:viewForRow:forComponent: (Listing 13-16).
  2. Add the images png, wizard.png, and tux.png to the project. You can find these images in the book’s resources folder.

            Modify the MyPickerDelegate’s init: method so it loads UIImageViews rather than strings into myData (Listing 13-16).

  1. Modify the pickerView:didSelectRow:inComponent: so it only logs the row and component to the debugger console (Listing 13-16).
  2. Save and build.
  3. Open xib and remove the button.
  4. Save and exit Interfacebuilder.
  5. Click Build And The application loads the images into the UIPickerView (Figure 13- 14).

NOTE

Notice that the pickerView:viewForRow:forComponent method takes a UIView. So, similar to custom table cells, you can also create custom picker rows using a UIView.

 

Figure 13-14 A UIPickerView that uses UIImageView objects as its components

 

Slide132

 

 

 

Listing 13-16 MyPickerDelegate.m modified to load images into the UIPickerView

#import “MyPickerDelegate.h”

@implementation MyPickerDelegate

@synthesize myData;

– (id) init {

if([super init] == nil) return nil;

UIImageView * one = [[UIImageView alloc] initWithImage:[[UIImage alloc]

initWithContentsOfFile: [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@”wizard.png”]]];

UIImageView * two =[[UIImageView alloc] initWithImage:[[UIImage alloc]

initWithContentsOfFile: [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent: @”tux.png”]]];

UIImageView * three =[[UIImageView alloc] initWithImage:[[UIImage alloc]

initWithContentsOfFile: [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@”money.png”]]];

myData = [[NSArray alloc] initWithObjects:one,two,three,nil]; return self;

}(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent: (NSInteger)component {

NSLog(@”picked row: %i, component: %i”, row, component);

}(NSInteger) numberOfComponentsInPickerView: (UIPickerView *) pickerView {

return 1; }(NSInteger) pickerView: (UIPickerView *) pickerView numberOfRowsInComponent: (NSInteger) component {

 

return [self.myData count];

}(UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger) row forComponent:(NSInteger)component reusingView:(UIView *)view { return [self.myData objectAtIndex:row];

}

@end

Summary
Review Date
Reviewed Item
Picker View Processing
Author Rating
5

“At TekSlate, we are trying to create high quality tutorials and articles, if you think any information is incorrect or want to add anything to the article, please feel free to get in touch with us at info@tekslate.com, we will update the article in 24 hours.”

0 Responses on Picker View Processing"

    Leave a Message

    Your email address will not be published. Required fields are marked *

    Site Disclaimer, Copyright © 2016 - All Rights Reserved.

    Support


    Please leave a message and we'll get back to you soon.

    I agree to be contacted via e-mail.