Sunday, January 4, 2009

Auto-rotating Tab Bars on the iPhone

This post is a quick summary of what's needed to get a tab bar (like the one in the Clock application) to switch from portrait to landscape when the user rotates their phone. Accelerometer goodness, yum!

The process is easy, but it has a couple of pitfalls. Here are the steps:

You have to override shouldAutorotateToInterfaceOrientation: in the view controllers forall the views in the tab bar. If a view controller's shouldAutorotateToInterfaceOrientation: returns NO, then the tab bar will not rotate, even if the view is hidden at the time of the rotation.

You should not override the tab bar controller's version of shouldAutorotateToInterfaceOrientation:

For regular views in the tab bar add the code below to viewDidLoad. If you skip this, your view will not resize when the phone is rotated while it's selected. However, it will resize when the user transitions to it from another view.

Make sure the controls on your regular views respond to changes in view size. If you're using Interface Builder's springs and struts, you can test the views right in IB, using the arrow at the right of the views' title bars.

Acknowledgements: I used the knowledge in some forum posts that Google revealed to me, together with some testing.

I hope you found this useful. If you have more tips, please post them in the comments, and I'll edit the posting accordingly, so others can have an easier time finding this information.

12 comments:

[I apologize for leaving/deleting multiple, no way to edit comments apparently]

Hey Victor, thanks for posting this. I'm curious why you advise not to override the UITabBarController's shouldAutoRotate... method? I feel like the SDK is lacking in this regard - what if you have a view controller in one tab that you want to rotate, but others you do not want to rotate? Shouldn't UITabBarController's shouldAutoRotate method go something like:

While debugging this problem, I found that the UITabController's shouldAutoRotateToInterfaceOrientation: method calls the same method in all the view controllers under the tab view (at least in 2.2).

I think it's a bad idea to override the tab controller's method because, when I did that, the tab view rotated together with the sub-views, but the sub-views' layout was not recomputed. So the sub-views did not become "wide".

Regarding your situation... I hope you have good reasons for supporting auto-rotation only in some views. As a user, I wouldn't be very happy if I were in a wide view, clicked on a tab, and the tab bar suddenly disappeared from under my fingers.

Victor, I have been trying to get my tab bar to rotate for a week now without being successful, even after reading this article. Could you post an xcode project containing a working implementation of an auto-rotating tab bar?

Short Bio

Victor Costan got infected with a passion for coding at the age of 10, and proceeded to earn a M.Eng in Computer science from MIT. Victor also holds a B.S. in Management that he pursued as he fell prey to the belief that great software requires legions of developers manipulating bloated code bases in repetitive ways. Thanks to Paul Graham's essays, Ruby, and Rails, he re-discovered the joy of coding, and came back from the dark ways of management.

Nowadays, Victor is still crazy about building software that he can impress his friends with, but he also dreams of contributing to making coding even more enjoyable. Victor likes developing mobile and Web 2.0 applications, and occasionally enjoys building some distributed systems behind the apps. When he is not coding, you will most likely find him reading up on some new programming language or software development technique.

At times, Victor likes to pretend he's mentally sane, and can be seen catching up with friends, watching a movie, or exploring Boston.