Handling rotations in UIViewController

In this post I’ll give a few general tips for handling device rotations at the UIViewController level.  These tips are for code using iOS (formerly known as iPhone OS) 3.0 or later, which includes all iPad code.

1.  In willAnimateRotationToInterfaceOrientation:duration:, size and position the view for the new orientation.

This sounds obvious and easy, but there are a lot of innocent-seeming ways to screw this up.

In this method, you can think of the rotation as being done, and that you’re now moving things to fit the new screen size.  You do not have to do any rotations yourself.  You do not have to make any calls to UIView’s animation methods.  UIKit handles both of those for you.

One way to think about your responsibility in this method is as follows: Imagine someone started with a tall skinny monitor as their only display, and then unplugged it and plugged back in a short wide monitor.  The

willAnimateRotationToInterfaceOrientation:duration:

method has the job of making things fit nicely on the new monitor.

But there are still some easy mistakes to make, as we’ll see.

2.  Use interfaceOrientation, and nothing else, to determine your orientation.

It can be tempting to use something like

self.frame.size.width

to determine if you’re in portrait or landscape mode, but this is a terrible idea for a few reasons:

  1. During the call to
    willAnimateRotationToInterfaceOrientation:duration:

    , the actual bounds of your view has not yet changed to the new orientation.

  2. If your view controller has the top-level non-window view (i.e., it’s the bottom-most view controller), then
    self.frame

    is always in portrait orientation.  Wha?  Yes, always in portrait – what changes is the transform of your view.  So your

    self.bounds

    is always accurate (keeping in mind the last point), but

    self.frame

    may or may not give the aspect ratio that the user is really seeing, since each view’s frame is reported in terms of the superview’s coordinates, and takes into account any transforms applied to the view.

  3. In general, it’s good to use a consistent and reliable method to determine orientation.  When you first start the app, your best bet is to refer to
    self.interfaceOrientation

    , and to use the helpful macros designed to work with the type

    UIInterfaceOrientation

    (see here for more details on that).  To keep your code consistent, it makes sense to use

    UIInterfaceOrientation

    variables in all situations where orientation is important.

3.  Don’t do extra work that you think may be needed for rotation.

In particular, there’s no need to adjust any view’s transform directly, since it’s done for you.  And you don’t have to think in terms of rotated coordinates either – the point (0,0) is always the upper-left corner of the user’s screen, and this point is moved for you automatically during rotation.

If you’re using iOS 3.0 or later (as this post assumes), then you also don’t want to implement the older functions 

willAnimate{First,Second}HalfOfRotationToInterfaceOrientation:duration:

methods.  This old system is considered less efficient and deprecated.  If you try to implement both the new technique (the single method above) and the old technique (the two-step methods here), then only the new technique will actually be executed at runtime.

4. Don’t forget to report that you handle all orientations.

If you don’t override the 

shouldAutorotateToInterfaceOrientation:

method of

UIViewController

, then the default implementation of this method will always return

NO

, and you’ll be stuck in portrait mode forever.  It’s a one-line method to rotate to any orientation – ”

return YES;

” – and that’s more-or-less required behavior for non-immersive apps on the iPad.

References

UIViewController class reference

UIInterfaceOrientation docs

2 Trackbacks

  1. By Dizzey.com on August 30, 2010 at 1:46 am

    Handling layout on UIInterfaceOrientation change…

    Responding to view rotation events and handling layout changes on device rotation. This blog explains techniques for modifying UI layout on UIInterfaceOrientation change…….

  2. By iOS開発備忘録 | source lab. note on December 24, 2011 at 7:01 pm

    […] Bynomial Code » Handling rotations in UIViewController pngも含めた透過性のviewはスクロール負荷が高い。 [iOS] TableView […]

Post a Comment

Your email is never published nor shared. Required fields are marked *

*
*