PickerView Workshop 2

In last week’s workshop, you learned the basics of using the PickerView control. In this week’s workshop, you will learn how to do the follow:

  • Display two components in the PickerView control.
  • Populate one component of the PickerView control with text strings; the other with images.
  • Display the item the user picked in a TextView control, alone with descriptive text

Design The SecondViewController Interface

To learn how to do above mention tasks, you’ll need to launch the PickerView application in Xcode, then click the SecondViewController.xib file to launch it in Interface Builder.

Currently, the view has only a Label control, displaying the text Second View. You need to add a PickerView control and TextView control on the view, so it look like this in Interface Builder. For the PickerView control, I want you to remove the check mark for the property, User Interaction Enabled.

pickerview_fig6

Next, use the Assistant editor to create and connect IBOutlet property variables (shown below) for the view’s PickerView control and the TextView control. Source code below also shows other property variables you need to add in the file.

SecondViewController.h

#import <UIKit/UIKit.h>

@interface SecondViewController : UIViewController

@property (strong, nonatomic) IBOutlet UIPickerView *pickerView;

@property (strong, nonatomic) IBOutlet UITextView *txtvwShopCart;

@property (strong, nonatomic) NSArray *productPhotoList;

@property (strong, nonatomic) NSArray *productNameList;

@property (nonatomic,strong) NSMutableDictionary *shoppingCartDictionary;
@end

Now is a good time as any to conform the SecondViewController class to the PickerView control’s protocol, via the Connection inspector window.
pickerview_fig2

Implement The PickerView DataSource Methods

Now that you’ve connected the view’s controls and conformed the SecondViewController class to the PickerView’s protocols, I want you to add these dataSource methods of the PickerView control in the SecondViewController.m file.

/* The PickerView control dataSourc methods */
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
  return 2;
}

- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
  if ([pickerView tag] == 0)
    return self.productNameList.count;
  else
  return self.productPhotoList.count;
}

The Project’s Photos

Download these images and add them in the project’s Supporting Files folder. They contain images you will use in the PickerView control.

pickerview_images

Implement The PickerView Delegate Methods

When the user tap the Second View tab, he will see the PickerView control populated with rows in two components and an empty TextView control, as shown in the image below. You will have to implement the reusingView: delegate method of the PickerView control to display rows in both components.

pickerview_fig7

With that said, here’s the code to add in the PickerView’s reusingView: delegate method.

/* The PickerView delegate methods */
- (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view {
  if (component == 0) {
    // return a label
    UILabel *productLabel = [[UILabel alloc] initWithFrame:CGRectMake(0,0,105,32)];
    productLabel.backgroundColor=[UIColor clearColor];
    productLabel.text=[self.productNameList objectAtIndex:row];
    return productLabel;
  } else {
    // return an image
    UIImageView *productImage = [[UIImageView alloc] initWithImage:
    [UIImage imageNamed:[self.productPhotoList objectAtIndex:row]]];
    return productImage;
  }
}

The user scroll component one then pick an item (a row). The PickerView control respond by displaying the item the user picked, along with descriptive text in the TextView control. You will have to implement the didSelectRow: delegate method of the PickerView control to activate the row picking event. Every time the user pick an item from component one, the PickerView update output shown in the TextView control. Say the user picked three items, the TextView control will display output similar to this image.

pickerview_fig8

Here is the code to implement the PickerView’s didSelectRow: delegate method.

-(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
  // Set up the shoppingCartDictionary object's Key and Value
  NSString *prodName=[self.productNameList objectAtIndex:row];
  NSNumber *photo=[self.productPhotoList objectAtIndex:row];

  if (component==0 && row==0) {
    // The user selected the Toy Car, so add it in the shoppingCartDictionary
    [self.shoppingCartDictionary setObject:photo forKey:prodName];

    // Highlight the rows of both components
    [self.pickerView selectRow:0 inComponent:0 animated:YES];
    [self.pickerView selectRow:0 inComponent:1 animated:YES];

  } else if (component==0 && row==1) {
    // The user selected the Wine Glass, so add it in the shoppingCartDictionary
    [self.shoppingCartDictionary setObject:photo forKey:prodName];

    // Highlight the rows of both components
    [self.pickerView selectRow:1 inComponent:0 animated:YES];
    [self.pickerView selectRow:1 inComponent:1 animated:YES];

  } else if (component==0 && row==2) {
    // The user selected the Small TV, so add it in the shoppingCartDictionary
    [self.shoppingCartDictionary setObject:photo forKey:prodName];

    // Highlight the rows of both components
    [self.pickerView selectRow:2 inComponent:0 animated:YES];
    [self.pickerView selectRow:2 inComponent:1 animated:YES];

  } else if (component==0 && row==3) {
    // The user selected the Toy Jeep, so add it in the shoppingCartDictionary
    [self.shoppingCartDictionary setObject:photo forKey:prodName];

    // Highlight the rows of both components
    [self.pickerView selectRow:3 inComponent:0 animated:YES];
    [self.pickerView selectRow:3 inComponent:1 animated:YES];

  } else if (component==0 && row==4) {
    // The user selected the Dog, so add it in the shoppingCartDictionary
    [self.shoppingCartDictionary setObject:photo forKey:prodName];

    // Highlight the rows of both components
    [self.pickerView selectRow:4 inComponent:0 animated:YES];
    [self.pickerView selectRow:4 inComponent:1 animated:YES];

  } else if (component==0 && row==5) {
    // The user selected the Office Phone, so add it in the shoppingCartDictionary
    [self.shoppingCartDictionary setObject:photo forKey:prodName];

    // Highlight the rows of both components
    [self.pickerView selectRow:5 inComponent:0 animated:YES];
    [self.pickerView selectRow:5 inComponent:1 animated:YES];

  } else if (component==0 && row==6) {
    // The user selected Flowers, so add it in the shoppingCartDictionary
    [self.shoppingCartDictionary setObject:photo forKey:prodName];

    // Highlight the rows of both components
    [self.pickerView selectRow:6 inComponent:0 animated:YES];
    [self.pickerView selectRow:6 inComponent:1 animated:YES];
  }
  // Convert the dictionary's keys to strings
  NSString *textProdNames = [[self.shoppingCartDictionary allKeys componentsJoinedByString:@"\n"];

  // Display content of the shoppingCartDictionary in the TextView control, along with the number items in it
  self.txtvwShopCart.text = [NSString stringWithFormat:@"Items in Your Shopping Cart [%i]\n---------------------------------\n%@",[self.shoppingCartDictionary count],textProdNames];
}

Code in above method is lengthy but if you read comments and look at above image, you should have no problem understanding the source code.

Add Code in The ViewDidLoad Method

The PickerView control data source consist of two NSArray methods and you declared them in the SecondViewController interface file. Now, you need to initialize both of them in the SecondViewController file’s viewDidLoad method. It is a good idea to initialize the shoppingCartDictionary property variable as well.

- (void)viewDidLoad
{
  [super viewDidLoad];
  // Initialize array property variables
  self.productNameList = @[@"Toy Car",
  @"Wine Glass",
  @"Small TV",
  @"Toy Jeep",
  @"Dog",
  @"Office Phone",
  @"Flowers"];

  self.productPhotoList = @[@"redcar_icon.png",
  @"87-wine-glass.png",
  @"70-tv.png",
  @"jeep.png",
  @"dog.png",
  @"office-phone.png",
  @"flowers-icon.png"];

  // Initialize the dictionary property variables
  self.shoppingCartDictionary = [[NSMutableDictionary alloc] init];
}

Add Code in The ViewDidAppear Method

To highlight the third row in both components of the PickerView control, I want you to add this method in the SecondViewController.m file. By the way, this method’s code is fired just before the view is loaded in the simulator window.

- (void) viewDidAppear:(BOOL)animated {
  // Set components' rows to highlight
  [self.pickerView selectRow:2 inComponent:0 animated:YES];
  [self.pickerView selectRow:2 inComponent:1 animated:YES];
}

Run The Application

You’ve entered necessary code to make the SecondView’s interface useable. Run the application to test the SecondViewController’s PickerView control.

next-iconThat’s it for this week’s workshop. In next week’s workshop, you will learn how to display images and text in a single component of a PickerView control. Until then, happy coding. 🙂