Sunday, May 31, 2009

Workaround for UIPicker / UIDatePicker landscape bug

There's an odd bug with the UIPicker and UIDatePicker classes on the iPhone when used in a landscape orientation. Rather than rendering as would be expected, the UIDatePicker is shifted to the right by about 50 pixels and the height is wrong. Even worse, if you decide to change the date format to be a count down timer (myPicker.datePickerMode = UIDatePickerModeCountDownTimer), you get a not so nice view like this:

After searching a bit on the various iPhone developer forums, I noticed different people mention that the problem only occurs if your view is already in landscape mode. If the view is first in portrait and you rotate the view to landscape, then the picker is rendered properly during the auto-rotation. This bit of information led me to a simple workaround for getting a properly rendered picker in landscape without having to have the user see a portrait version of the view first.

All you have to do is fake some part of the underlying UI into thinking you are in portrait mode even though your aren't. I have no idea why this works, but it does. I've already wasted too many hours on this annoying bug, so I settled on this hack. (I'm very surprised Apple still has this obvious bug in the SDK when we are coming up on a 3.0 release, but it's there. And yes, people have logged bug reports about it. Ok, enough of my side rant.)

So, how do you do this bit of trickery? Assuming your main app is already in landscape mode, you can do the following in the view controller for the view containing the picker view:

-(void)viewWillAppear: (BOOL)animated {

// Fake the UI rendering to think we are in portrait orientation
[[UIApplication sharedApplication] setStatusBarOrientation: UIInterfaceOrientationPortrait animated: YES];


For some reason, this causes the picker view to render properly even though the view really does remain in landscape mode. My countdown timer picker now looks good and proper:

That's it. Just one line of code and the landscape rendering of a picker is fixed. Again, I have no idea why. Perhaps someone more in touch with the inner workings of Cocoa will point out the reason why this hack works.

As a somewhat humorous aside, while searching (in vain) for a solution to this problem on various iPhone SDK forums, I did run into an odd feature of the official Apple developer forums (currently in beta). I typed in a search for "uipickerview uiinterfaceorientationlandscaperight" and the search came back with no matching results, but Apple was kinda enough to offer this helpful suggestion: "Did you mean: cupcake itinerancies?"


GaryM said...

I ran into the same problem while developing an app but this fix didn't seem to help.

However, I did find a different fix at which sets the UIPickerView's frame to the UIPicker's frame in viewDidLoad and that fixed this problem for me!

Mike said...

This works okay, but for me the labels in the date picker were misaligned after applying this patch. I created a workaround here:

All content copyright © 2009  Brian Stormont, unless otherwise noted.   All rights reserved.