iOS6: dynamic autorotation

One of the most intrusive changes brought by iOS6 is the way autorotation is handled in UIViewControllers. If you have an autorotating app for iOS5, you will need to change it to correctly support autorotation under iOS6. If you develop an app which is supposed to run both on iOS5 and iOS6, then you will have to handle autorotation in the old as well as the new way.

In this post, I am going to provide a simple solution to a problem which, as much as I have been seeing around me, has not an entirely trivial solution. The problem statement is the following: a view which is allowed to autorotate only under certain conditions; otherwise, it will be frozen (as far as autorotation is concerned).

E.g., you take a screenshot of your UI at a given moment, then display it, maybe applying some effects to it. If the device is rotated in this context, your overall UI will rotate accordingly, while the snapshot you took will not (it will still reflect the initial device orientation). Now, what you want is freezing autorotation while the snapshot is shown. Another example: on top of your fully “elastic” UI, you display some piece of information which is not meant to autorotate. Again, what you want is freezing autorotation while that piece of information is displayed.

Under iOS5, this was really straightforward, because each time an autorotation event is detected, UIkit sends your controllers the shouldAutorotateToInterfaceOrientation: message. There you have a chance to deny autorotating to a specific interface rotation according to your criteria.

Under iOS6, it is equally straightforward except for the unlucky naming of the cornerstone iOS6 autorotation method, namely shouldAutorotate. What that name leads you (or at least me) into thinking is that you can decide there whether (and when) your view can autorotate. Wrong. The shouldAutorotate method does actually respond to an optimisation purpose: if your view controller shouldAutorotate returns NO, then the framework will not forward any autorotation messages to it.

So, if you want to control the conditions under which your controllers autorotate, you will have to either leave that method undefined or define it as to always return YES. The real “meat” of automation control is thus given in the supportedInterfaceOrientations method. E.g., it could be defined as:


- (NSUInteger)supportedInterfaceOrientations {

    if ([self canAutorotateNow])
        return UIInterfaceOrientationMaskAll;
    
    if (UIInterfaceOrientationIsLandscape([UIApplication sharedApplication].statusBarOrientation))
        return UIInterfaceOrientationMaskLandscape;
    return UIInterfaceOrientationMaskPortrait;
}

You see, the idea is checking if the autorotation is frozen at the moment supportedInterfaceOrientations is called; if it is, then only return as a supported orientation the one corresponding to the current status bar orientation.

Copyright © Labs Ramblings

Built on Notes Blog by TDH
Powered by WordPress

That's it - back to the top of page!