Print PDF

Rotating UIPickerView between landscape and portrait orientations

One of the UI improvements in the first update of Niftybean's index cards app iSpeechCards is support for both landscape and portrait orientation when editing card content.  When editing a card's duration there's a custom UIPickerView displaying hours and minutes.  This picker is positioned at the bottom of the screen and also scales and stretches in landscape.

Here's the simplest way I've been able to achieve this using Interface Builder layout and minimal code in the view controller. For this example I'm using a UIDatePicker but any UIPickerView will work.

The quick solution

Use this quick solution if you don't mind the UIPickerView height staying at the default 216 px.

  1. Create the elements and hook them into your code using IBOutlet
  2. Support both orientations in the view controller.
  3. Adjust the resizing mask in viewDidLoad:

Here are some shots from Interface Builder.


Interface Builder Elements


Interface Builder View

Here's the code.  It seems you can't change the autoresizing mask of a UIDatePicker or UIPickerView in Interface Bulider.

- (void)viewDidLoad {
  [super viewDidLoad];
  // Without this autoresizingMask it won't work.
  datePicker.autoresizingMask = UIViewAutoresizingFlexibleWidth |
    UIViewAutoresizingFlexibleTopMargin;
}
 
-(BOOL) shouldAutorotateToInterfaceOrientation:
        (UIInterfaceOrientation)orientation {
  return (orientation == UIInterfaceOrientationPortrait ||
            UIInterfaceOrientationIsLandscape(orientation));
}

Here's the result in landscape:

Landscape UIDatePicker without vertical scaling


The full solution

What I'm calling the full solution also resizes the height of the UIDatePicker.  This looks a lot nicer in landscape as the default 216 px doesn't leave much room for other UI elements.

  1. Create the elements and hook them into your code using IBOutlet (as before)
  2. Support both orientations in the view controller (as before)
  3. Don't adjust the resizing mask!
  4. Implement willAnimateRotationToInterfaceOrientation:duration: and a little extra code, specifically hard coding the UIPickerView heights we want.


-(void) viewWillAppear:(BOOL)animated {
  [super viewWillAppear:animated];
  // Layout once here to ensure the current orientation is respected.
  [self layoutPicker:[UIApplication sharedApplication].statusBarOrientation];
}
 
-(BOOL) shouldAutorotateToInterfaceOrientation:
        (UIInterfaceOrientation)orientation {
  return (orientation == UIInterfaceOrientationPortrait ||
    UIInterfaceOrientationIsLandscape(orientation));
}
 
// Use frame of containing view to work out the correct origin and size
// of the UIDatePicker.
-(void) layoutPicker:(UIInterfaceOrientation)orientation {
  CGFloat newPickerHeight = UIInterfaceOrientationIsLandscape(orientation) 
                             ? 170 : 216;
  datePicker.frame = CGRectMake(0,
                             self.view.frame.size.height - newPickerHeight, 
                             self.view.frame.size.width, newPickerHeight);
}
 
- (void)willAnimateRotationToInterfaceOrientation:
         (UIInterfaceOrientation)orientation
     duration:(NSTimeInterval)duration {
  [self layoutPicker:orientation];
}
 

And this is how the full version looks in landscape:

Landscape UIDatePicker with vertical resizing

Warning - your mileage may vary with different landscape picker heights!

For some reason UIPickerView and UIDatePicker resize their inner views differently when their frame is set with different heights.  With some values it works fine but other values cause the layout to look messed up and awful.  If you're going to resize the height of a picker view be sure to test it thoroughly.  While experimenting with iPhone OS 3.1.3 I found that 170px works fine for a UIDatePicker and 180 worked fine for the mins/seconds custom UIPickerView.


 

Add your comment

Your name:
Subject:
Comment:
  The word for verification. Lowercase letters only with no spaces.
Word verification:

View in the App Store

Niftybean Blog


Subscribe

Contact Us

Contact Us

Email us or reach us using details below

  • Address:
    PO Box 11463, Manners St Central, Wellington
  • Tel:
    (64)-4-550-3887


NZiPhone.com

iphonewzealand.co.nz

Search site

Login