Two UIPickerView together in one ViewController Programatically

| June 16, 2011 | 10 Comments

We will add two pickerviews programmatically.

Goal: we want to add two pickerviews in one viewcontroller. By pressing on a button will display a pickerview and when we will select from any of the pickerview its selected row will be displayed on button. When one button is pressed if other pickerview is on screen we will remove it. Also if user touches on any other part of the screen, both pickerviews will hide and removed.

Are your ready to Start?

Open the Xcode, From the file menu select New Project. Name the project PickerViewExample. Now add another view controller from Class->New->add File now select UIViewControllerSubClass. Check with Xib option and leave other as uncheck. HomeViewController is the class where we will create our two pickerviews.

Now open the HomeViewController.h and write following code


@interface HomeViewController : UIViewController
< UIPickerViewDataSource,UIPickerViewDelegate> {
	UIPickerView *countryTypePicker;
	UIPickerView *categoryTypePicker;
	NSArray *countryTypes;
	NSArray *categoryTypes;
	IBOutlet UIButton *countryTypeBtn;
	IBOutlet UIButton *categoryTypeBtn;
      NSArray *pickersArray;
    UIPickerView *activePickerView;
@property (nonatomic,retain)     UIPickerView *activePickerView;
-(IBAction) showCountryTypePicker;
-(IBAction) showCategoryTypePicker;

Open the HomeViewController Nib and add two buttons. One button will contain selected country and one will contain select category.Assign tag 0 and 1 to both these buttons. Also there are two function attached with buttons showCountryTypePicker and ShowCategoryTypePicker.

Now under first line of HomeViewController add following lines


first line shows number of columns in each picker while second and third line are unique tags that we will assign to each picker.

 - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization.
		categoryTypes = [[NSArray alloc] initWithObjects:@"Appetizers",@"Breakfast",@"Dessert",@"Drinks",
						 @"Main Dish/Entree", @"Salad", @"Side Dish", @"Soup", @"Snack",
						 @"Baby Food", @"Pet Food",nil];  

		countryTypes = [[NSArray alloc] initWithObjects:@"African",@"American",@"Armenian",@"Barbecue",
						 @"Brazilian", @"British", @"Cajun", @"Central American", @"Chicken",
						 @"Chinese", @"Cuban",
						 @"Ethiopian", @"French", @"Greek", @"German", @"Hamburgers",
						 @"Homestyle Cooking", @"Indian", @"Irish", @"Italian", @"Jamaican",
						 @"Japanese", @"Korean", @"Mexican", @"Middle Eastern", @"Pakistani",
						 @"Pancakes /Waffles", @"Persian", @"Pizza", @"Polynesian", @"Russian",
						 @"Sandwiches", @"Seafood", @"Scandinavian", @"Spanish", @"Soul Food",
						 @"South American", @"Steak", @"Vegetarian", @"Tex-Mex", @"Thai",
						 @"Vietnamese",@"Wild Game",nil];
    return self;

These are two arrays that we will bind with two pickers.
Now uncomment the viewDidLoad method and replace with following

- (void)viewDidLoad {
    [super viewDidLoad];
	categoryTypePicker = [[UIPickerView alloc] initWithFrame:CGRectMake(0,250,400,160)];
	categoryTypePicker.tag = kCATEGORYTYPEPICKERTAG;
	categoryTypePicker.showsSelectionIndicator = TRUE;
	categoryTypePicker.dataSource = self;
	categoryTypePicker.delegate = self;
	categoryTypePicker.hidden = YES;
	countryTypePicker = [[UIPickerView alloc] initWithFrame:CGRectMake(0,250,400,160)];
	countryTypePicker.backgroundColor = [UIColor blueColor];
	countryTypePicker.tag = kCUISINETYPEPICKERTAG;
	countryTypePicker.showsSelectionIndicator = TRUE;
	countryTypePicker.hidden = YES;
	countryTypePicker.dataSource = self;
	countryTypePicker.delegate = self;
pickersArray =  [[NSArray alloc] initWithObjects: categoryTypePicker, countryTypePicker ,nil];//add your both pickers to this array and we will use button tags to get picker from this array and alternate between two pickers

Initially both pickers will be hidden. We assigned different tag to each picker.
If we want to hide the pickerview if touched outside the button add your code to following method

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)eve

#pragma mark -
#pragma mark picker methods
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView

This method tells how many columns in each picker. We want one column in each picker.

- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
	if (pickerView.tag == kCATEGORYTYPEPICKERTAG)
		return [categoryTypes count];
		return [countryTypes count];


This method will tell how many rows in each picker based on tag it binds the relevant array.

- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
	if (pickerView.tag == kCATEGORYTYPEPICKERTAG)
		return [categoryTypes objectAtIndex:row];
		return [countryTypes objectAtIndex:row];

} //this mehtod shows title for each row in picker
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
	if (pickerView.tag == kCATEGORYTYPEPICKERTAG) {
		NSString *categoryType  = [categoryTypes objectAtIndex:[pickerView selectedRowInComponent:0]];
		[categoryTypeBtn setTitle:categoryType forState:UIControlStateNormal];	

	}else {

		NSString *countryType  = [countryTypes objectAtIndex:[pickerView selectedRowInComponent:0]];
		[countryTypeBtn setTitle:countryType forState:UIControlStateNormal];				


} //this method displays whenever selection indicator stops the row title is set as button title.
//Thanks to Nick Staresinic for pointing out this bug..
//call this function on both button clicks
-(IBAction) alternatePickers: (id) sender{	

        UIButton * control = (UIButton*) sender;
        if (self.activePickerView) {

            [self.activePickerView removeFromSuperview];

        NSLog(@"Segment index:%d",control.tag);
        self.activePickerView = [pickersArray objectAtIndex:control.tag];

        [self.view  addSubview:self.activePickerView];


In above method if one of the button is pressed we hide other picker and remove it from view if it there. From Interface builder please connect this method with each button on Touchupinside event.
Now comes the memory management part. Replace your dealloc with follow method.

- (void)dealloc {
	[countryTypes release];
	[categoryTypes release];
	[categoryTypePicker release];
	[countryTypePicker release];;
    [super dealloc];

We have done most of our work now we will add our HomeViewController to main window. Open the PickerViewExampleAppDelegate.h above the implementation tag add @class HomeViewController. add following line
HomeViewController *homeViewController;
Now open PickerViewExampleAppDelegate.m and add HomeViewController.h. Now replace your following function with this

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {    

    // Override point for customization after application launch.
    homeViewController = [[HomeViewController alloc] initWithNibName:@"HomeViewController" bundle:nil];
	[window addSubview:homeViewController.view];
    [self.window makeKeyAndVisible];

    return YES;

In its dealloc you will release [homeViewController release];
Click here to download source code.
Developer: Asif Noor (

Tags: , , , , , ,

Category: IPhone

Comments (10)

Trackback URL | Comments RSS Feed

  1. Asif Noor says:

    Thanks Nick Staresinic for pointing out bug in alternating between two pickers.It is fixed now and also source code is update.

  2. pooja says:

    Thankyou so much for this example. It saved me a lot of time. I’ve to implement multiple pickers in my app but I have a problem. I need the contents of one picker to change based on another picker’s selection. For example – The regions picker should change according to the country selected in the country picker. Any help would be greatly appreciated as I’m a newbie to Objective C. Thanks a lot in advance.

  3. Asif Noor says:


    What you do is following.
    When country in the country picker changes, you should fire a notification and catch that notification in other picker and in that observer reload your region values.
    Hope it helps.

  4. David says:

    Great tute, but what if I dont want to fire from a button, but a press on a table view cell?


    • Asif Noor says:

      You can use table view delegate method

      – (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

      When user presses any cell or row, this function will be called.

  5. Peter Rasmussen says:

    How does this datasource Work, how does the UIPickerView know what array to choose, when both is referred to as self.

    Greeting from Roskilde Denmark

  6. chaitanya says:

    -(IBAction) showCountryTypePicker;
    -(IBAction) showCategoryTypePicker;
    -(IBAction) alternatePickers: (id) sender;

    you are asking to put two buttons on NIB file and declared three methods to bind them. could you please clarify this.? i am trying your sample on XCode 7.

  7. chaitanya says:

    where is the code for these Actions:


  8. niraj nandha says:


    // ShippingViewController.h
    // Agrotrad
    // Created by MacBook Pro on 2/1/16.
    // Copyright (c) 2016 MacBook Pro. All rights reserved.


    @interface ShippingViewController : UIViewController

    __weak IBOutlet UIButton *btnsubmit;
    __weak IBOutlet UITextField *txtName;

    __weak IBOutlet UITextField *txtStatePickerView;

    __weak IBOutlet UITextField *txtCityPickerView;

    __weak IBOutlet UITextField *txtAreaPickerView;

    __weak IBOutlet UITextField *txtPinCode;

    __weak IBOutlet UITextField *txtAddress;
    __weak IBOutlet UITextField *txtMobileNo;

    – (IBAction)btnSubmitPayOrder:(id)sender;



    // ShippingViewController.m
    // Agrotrad
    // Created by MacBook Pro on 2/1/16.
    // Copyright (c) 2016 MacBook Pro. All rights reserved.

    #import “ShippingViewController.h”
    #import “BillingViewController.h”

    @interface ShippingViewController ()

    BillingViewController *bill;
    NSMutableArray * arrState;
    NSMutableArray * arrCity;
    NSMutableArray * arrArea;
    UIPickerView *pickerView1;



    @implementation ShippingViewController
    – (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view from its nib.

    self.title = @”Shipping Detils”;
    btnsubmit.layer.cornerRadius = 7;
    btnsubmit.clipsToBounds = YES;
    bill = [[BillingViewController alloc]init];

    arrState = [[NSMutableArray alloc]initWithObjects:@”Andhra Pradesh”,@”Arunachal Pradesh”,@”Goa”,@”Goa”,@”Gujarat”, nil];

    arrCity = [[NSMutableArray alloc]initWithObjects:@”Ahmedabad”,@”Surat”,@”Vadodara”,@”Rajkot”,@”Bhavnagar”, nil];

    arrArea = [[NSMutableArray alloc]initWithObjects:@”BapuNagar”,@”PrahladNagar”,@”C.G.Road”,@”S.G. Road”,@”Navrangpura”, nil];

    //PickerView Assing For Muliple…

    pickerView1 = [[UIPickerView alloc] initWithFrame:CGRectMake(0, 43, 320, 480)];
    pickerView1.delegate = self;
    pickerView1.dataSource = self;
    [pickerView1 setShowsSelectionIndicator:YES];
    txtStatePickerView.inputView = pickerView1;
    txtStatePickerView.tag = 1;

    txtCityPickerView.inputView = pickerView1;
    txtCityPickerView.tag = 2;

    txtAreaPickerView.inputView = pickerView1;
    txtAreaPickerView.tag = 3;


    – (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.

    #pragma mark – Navigation

    // In a storyboard-based application, you will often want to do a little preparation before navigation
    – (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    // Get the new view controller using [segue destinationViewController].
    // Pass the selected object to the new view controller.

    – (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView

    if(txtStatePickerView.tag == 1){
    return [arrState count];
    else if (txtCityPickerView.tag == 2){
    return [arrCity count];
    return [arrArea count];

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

    if(txtStatePickerView.tag == 1)
    return [arrState count];

    else if (txtCityPickerView.tag == 2){
    return [arrCity count];

    return [arrArea count];


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

    if(txtStatePickerView.tag == 1)
    return [arrState objectAtIndex:row];

    else if (txtCityPickerView.tag == 2){
    return [arrCity objectAtIndex:row];
    else {

    return [arrArea objectAtIndex:row];


    – (IBAction)btnSubmitPayOrder:(id)sender {

    [self.navigationController pushViewController:bill animated:YES];


    Only One Object Pass For One Time

Leave a Reply