Horizontal UIPickerView

A situation can arise when you want to have some horizontal UIPickerView in your application.

Something like what in the picture shown below

horizontal_pickerview

Following code will draw one like that..

-(void)loadView:{
// Write code to create self.view
// Then...
pickerViewArray = [[NSArray arrayWithObjects:
 @"John Appleseed", @"Chris Armstrong", @"Serena Auroux",
 @"Susan Bean", @"Luis Becerra", @"Kate Bell", @"Alain Briere",
 nil] retain];
 myPickerView = [[UIPickerView alloc] initWithFrame:CGRectZero];
 myPickerView.delegate = self;
 myPickerView.showsSelectionIndicator =YES;
 myPickerView.backgroundColor = [UIColor clearColor];
 CGAffineTransform rotate = CGAffineTransformMakeRotation(-3.14/2);
 rotate = CGAffineTransformScale(rotate, 0.25, 2.0);
 [self.myPickerView setTransform:rotate];
 [self.view addSubview:myPickerView];
} 

// UIPickerViewDelegate

- (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view{
	CGRect rect = CGRectMake(0, 0, 120, 80);
	UILabel *label = [[UILabel alloc]initWithFrame:rect];
	CGAffineTransform rotate = CGAffineTransformMakeRotation(3.14/2);
	rotate = CGAffineTransformScale(rotate, 0.25, 2.0);
	[label setTransform:rotate];
	label.text = [pickerViewArray objectAtIndex:row];
	label.font = [UIFont systemFontOfSize:22.0];
	label.textAlignment = UITextAlignmentCenter;
	label.numberOfLines = 2;
	label.lineBreakMode = UILineBreakModeWordWrap;
	label.backgroundColor = [UIColor clearColor];
	label.clipsToBounds = YES;
	return label ;
}

Courtesy: Syed Yusuf

30 thoughts on “Horizontal UIPickerView

  1. pramod says:

    I would like to know , Do Appstore will have any objection for the app to be submitted if we modify the standard controls size or the way it was supposed to be used as per IPHONE HIG(Human interface guidelines)

  2. I don’t think there is such kind of objection from Apple ( however i am not ruling out that).
    I have tried customizing the alertviews/actionsheets (in shape, color etc..) and successfully uploaded to app store.

    I think Apple don’t stand against your creativity/ideas 🙂 🙂
    However its not advisable to use undocumented APIs, even though you can run the app without any error/warning. They will reject such apps.

    Happy Coding . . . .

  3. nebyate says:

    while creating my Horizontal picker

    I got a problem with:
    [self.picker setTransform:rotate];

    error:

    accessing unknown ‘picker’ getter method

    • Just type ‘ UIPickerViewDelegate’ and ‘Jump to definition’ .
      You can find the delegate methods there.
      Please make it clear what you are trying to achieve so that i can help you better. Dont forget to set pickerInstance.delegate = self 🙂

  4. Jay says:

    thanks for the tip!

    One thing I ran into when I tried this technique was that all my picker views were displayed upside down. On line 23 where the rotation of the label is computed, I’m pretty sure it should be :

    CGAffineTransform rotate = CGAffineTransformMakeRotation(-3.14/2); // note the negative sign

    this would rotate the label 90 degrees counter-clockwise relative to the rotation applied to the PickerView.

  5. Hi,

    i added a dataSource to to get it working:

    #pragma UIPickerViewDataSource

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

    – (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
    return [pickerViewArray count];
    }

    and in loadview:

    myPickerView.dataSource = self;

    What i can’t figure out is how to make the picker smaller in height (or width before the rotation) initializing with a different frame only affects the y offset. Like to put it on the top of the screen i do:

    myPickerView = [[UIPickerView alloc] initWithFrame:CGRectMake(0, -68, 0, 0)];

    any ideas?

    regards

    Chris

  6. Brilliant, I’ve been looking for a way to do this for quite some time.
    I suppose if you want a picker less heigh one could transform with .5 and invert the transform on the label but I haven’t figured out that yet

  7. Vilem says:

    I am quite new to iphone programming so I suppose this is stupid question, but please answer anyway, I am just learning everything 🙂

    I can not get values on picker – something is wrong with the delegate, or delegate assingment. But I do not understand – the delegate method wants back UIView class, and you return UILabel? Is that right?

  8. Ganesh Krishnan says:

    I am not able to get the same in a UITableViewCell. It just refuses to show if I add it as a subview. Can you point what I may be missing?

  9. I think that’s :
    CGAffineTransform rotate = CGAffineTransformMakeRotation(-3.14/2);

    So with a -3.14 on line 23 only (It was upside/down with the code just copied and pasted!

    Great anyway, thanks!

  10. Thnx for this tutorial. I’m having some problems plz help me. I copy pasted loadView code in my viewDidLoad method. Created UIPickerView *myPickerView; and NSArray *pickerViewArray in my .h file. There is no compilation error but text is not shown on picker. can you help me plz… 🙂

  11. faisal says:

    Thanks, this is very helpful, I have a problem I would appreciate if you can help, I used the above code but the text is upside down?? I tried changing all the angels no help, any idea??

    • @macro
      The code is only that much. loadView and the delegate are enough.
      You want to write numberofRows delegate methods as well.

      I dont have the full code right now, and i did this years before.

    • rita says:

      Thanks for this great code. Very useful. I am copying the full source code for .h and .m files of View Controller below. I used a View-Based app template of Xcode 4 to start with.

      #import

      @interface MyHorizontalPickerViewViewController : UIViewController {

      NSArray *pickerViewArray;
      UIPickerView *myPickerView;
      }

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

      @end

      #import “MyHorizontalPickerViewViewController.h”

      @implementation MyHorizontalPickerViewViewController
      @synthesize myPickerView;

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

      -(NSInteger)pickerView:(UIPickerView *)myPickerView numberOfRowsInComponent:(NSInteger)component {
      return [pickerViewArray count];
      }

      • (void)dealloc

      {
      [myPickerView release];
      [super dealloc];
      }

      • (void)didReceiveMemoryWarning

      {
      [super didReceiveMemoryWarning];
      }

      • (void)viewDidLoad

      {
      pickerViewArray = [[NSArray arrayWithObjects:
      @”John Appleseed”, @”Chris Armstrong”, @”Serena Auroux”,
      @”Susan Bean”, @”Luis Becerra”, @”Kate Bell”, @”Alain Briere”,
      nil] retain];
      myPickerView = [[UIPickerView alloc] initWithFrame:CGRectZero];
      myPickerView.delegate = self;
      myPickerView.showsSelectionIndicator =YES;
      myPickerView.backgroundColor = [UIColor clearColor];
      CGAffineTransform rotate = CGAffineTransformMakeRotation(-3.14/2);
      rotate = CGAffineTransformScale(rotate, 0.25, 2.0);
      [self.myPickerView setTransform:rotate];
      [self.view addSubview:myPickerView];
      [super viewDidLoad];
      }

      • (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view{

      CGRect rect = CGRectMake(0, 0, 120, 80);
      UILabel *label = [[UILabel alloc]initWithFrame:rect];
      CGAffineTransform rotate = CGAffineTransformMakeRotation(3.14/2);
      rotate = CGAffineTransformScale(rotate, 0.25, 2.0);
      [label setTransform:rotate];
      label.text = [pickerViewArray objectAtIndex:row];
      label.font = [UIFont systemFontOfSize:22.0];
      label.textAlignment = UITextAlignmentCenter;
      label.numberOfLines = 2;
      label.lineBreakMode = UILineBreakModeWordWrap;
      label.backgroundColor = [UIColor clearColor];
      label.clipsToBounds = YES;
      return label ;
      }

      • (void)viewDidUnload

      {
      [myPickerView release];
      myPickerView = nil;
      [self setMyPickerView:nil];
      [super viewDidUnload];
      }

      @end

  12. mike says:

    i am not able to position the picker view correctly. it somehow appears at the center of the screen while i want it to be on the top of the view.

    • @mike
      You can override the position of the view at any point.
      Play with the setFrame: method to position the pickerView wherever you want.
      Note that there is a combination of rotation/scaling transform for the pickerview.

  13. yassmeen hussein says:

    Thanks for the very useful code,
    I have a question though,what if i want two components inside my horizontal UIPicker view, how can i do it?

  14. Erum says:

    please let me know i m following your tutorial its working fine in ios 5.0 but when i m trying to add any label or navigation bar then it is not displaying anything on run time even it’s connected properly but only a picker is present at run time kindly reply me .

  15. hi everyone,
    this is a nice tutorial for horizontal picker with few corrections in that. In the rotation in view did load method use -3.14 instead of 3.14. and by adding datasource with two methods that are stated above this is will work fine.

Leave a reply to Sujith Krishnan Cancel reply