Controlling Screen Orientation of iOS Apps

By default an iOS app will support all possible orientations (landscape, portrait left, portrait right, etc.). When a user rotates the device the app will automatically rotate to fill the screen. In many cases this may not be a desirable behavior. For example, your app may have been designed for portrait mode only. In more complex cases you may have to support different orientations for different screens of the app. For example, a video player must work in either portrait or landscape mode where as the rest of the app only supports portrait.

The process to control how the app behaves when the screen is rotated can be a bit confusing. This article will shed some light on the issue.

Global Configuration

There are two ways you can set the supported orientation for the entire app (for all controllers).

Using Info.plist

This is the easiest way to set the supported orientations for the whole app.

In Xcode select the target and from the General settings page turn on the check boxes for the supported orientations. You need to do that separately for iPhone and iPad.

From AppDelegate

Your app may have business logic that dynamically controls what orientations should be supported. For example, a video player page may support landscape only when a video is played in fullscreen. In such a case the Info.plist approach will not work. To dynamically control the app wide supported orientation implement the application: supportedInterfaceOrientationsForWindow: method from the AppDelegate class.

Important: If your AppDelegate implements that method iOS no longer uses the setting in Info.plist to control orientation.

Example:

- (UIInterfaceOrientationMask)application:(UIApplication *) application 
  supportedInterfaceOrientationsForWindow:(UIWindow *) window {

    if (self.allowLandscape == true) {
        return UIInterfaceOrientationMaskLandscapeLeft & 
            UIInterfaceOrientationMaskLandscapeRight;
    }

    return
       UIInterfaceOrientationMaskPortrait;
}

Per Controller Configuration

Individual controllers can specify what orientations they support. This is done via the supportedInterfaceOrientations property of the UIViewController.

Keep in mind a few key things:

  1. supportedInterfaceOrientations is a property and not a callback method. The way you override the getter method in Swift needs to take that into consideration.
  2. iOS will only query the root UIViewController or the topmost presented controller. For example, if you are using a navigation controller then you need to create a custom UINavigationController to override this property. The same goes for tab bar controller.
  3. iOS will intersect the supported orientations set in supportedInterfaceOrientations with the global setting (Info.plist or AppDelegate). Only the orientations common to both will be supported by the controller. So, for example, if supportedInterfaceOrientations is set to landscape left, make sure the same is enabled globally.

Example Objective-C code:

- (UIInterfaceOrientationMask) supportedInterfaceOrientations {
    return UIInterfaceOrientationMaskPortrait;
}

Example Swift code:

override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
    return UIInterfaceOrientationMask.landscapeLeft
}

The UIViewController class also has the shouldAutorotate boolean property. The default value is true. If you set it to false then the orientation will be locked to the current value. For example, let us say that a controller supports landscape and portrait. Currently the controller is in landscape mode. If the property is false then the controller will remain in landscape mode if the user rotates the screen to portrait mode. Use this property to only temporarily lock the orientation to the current orientation.

Example:

override var shouldAutorotate: Bool {  
        return false  
}  

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.