Why won't my UIViewController rotate with the device?
Why won't my
UIViewController rotate with the device?
UIViewController class provides the fundamental view-management model for iOS applications. It provides automatic support for rotating the views of the view controller in response to changes to the orientation of the device. If the autoresizing properties of your view and subviews are properly configured, this behavior is automatic in most cases. Here is a fairly exhaustive list of reasons a view controller may not rotate.
You have added your view controller's
UIWindowas a subview.
Developers are discouraged from adding the view property of any view controller as a subview of
UIWindow. Your application's root view controller should be assigned to the app window's
rootViewControllerproperty either in Interface Builder, or at runtime before returning from
application:didFinishLaunchingWithOptions:. If you need to display content from more than one view controller simultaneously, you should define your own container view controller and use it as the root view controller. See Creating Custom Container View Controllers.
Beginning with iOS 6, if a root view controller has not been assigned to the app's window, supported orientations are determined only by the
UIApplicationobject. Further, view controllers will not be notified of orientation changes, which may result in unexpected behavior.
The view controller does not support the new orientation.
Beginning with iOS 6, a view controller can limit its supported orientations by overriding this method:
The default implementation of
supportedInterfaceOrientationsreturns a rotation mask of the recommended orientation values for the current device's idiom. That is,
UIInterfaceOrientationMaskAllis returned on iPad devices and
UIInterfaceOrientationMaskAllButUpsideDownis returned on iPhone devices. There is little need to override this method unless the content managed by the view controller must only be displayed in a subset of these orientations. If you override this method, your implementation must return a bitwise combination of
On iOS 5 and below, a view controller can support multiple orientations by overriding this method:
shouldAutorotateToInterfaceOrientationis implemented, you should make sure it returns
YESfor all the orientations you wish to support. The default implementation returns
interfaceOrientationis equal to
UIInterfaceOrientationPortrait, locking the view controller into portrait orientation. To support all orientations, simply always return
The application does not support the same orientations as the view controller.
Beginning with iOS 6, UIKit uses both the
UIApplicationobject and the topmost view controller to determine the supported orientations. The
UISupportedInterfaceOrientationskey in the app's
Info.plistmust contain a value for each orientation your app supports. The system uses these values to derive the app's supported orientation mask. The application delegate may implement
application:supportedInterfaceOrientationsForWindow:to return a
UIInterfaceOrientationMaskthat is used in place of the values from the app's
On iOS 5 and below, the values for the
UISupportedInterfaceOrientationskey in the app's
Info.plistonly serve as a hint to Springboard that it should reposition the status bar before starting your app. They do not restrict the supported orientations of your app after it has been launched.
The view controller declined to rotate.
Beginning with iOS 6, when UIKit determines that rotation may need to occur, it calls the
shouldAutorotatemethod of the topmost view controller to determine whether to proceed with the rotation. The default implementation of this method returns
YES; however, a view controller may dynamically disable automatic rotation at runtime by overriding
The view controller is a child of another view controller.
Beginning with iOS 6, only the topmost view controller (alongside the
UIApplicationobject) participates in deciding whether to rotate in response to a change of the device's orientation. More often than not, the view controller displaying your content is a child of
UITabBarController, or a custom container view controller. You may find yourself needing to subclass a container view controller in order to modify the values returned by its
The view controller overrides
initWithNibName:bundle:but does not invoke the superclass' implementation. For the object to be initialized properly, you must call super on any
initWithNibNamemethod you are overriding in your view controllers.
All child view controllers in your
UINavigationControllerdo not agree on a common orientation set.
On iOS 5 and below, to make sure that all your child view controllers rotate correctly, you must implement
shouldAutorotateToInterfaceOrientationfor each view controller representing each tab or navigation level. Each must agree on the same orientation for that rotate to occur. That is, they all should return
YESfor the same orientation positions.
The view controller is altering the layout of its subviews programmatically.
Certain layouts are impossible to realize using autoresizing masks alone. A view controller can manually layout its subviews by altering their frame, bounds, or center properties. Developers should not place layout code in any of the rotation methods overridden by the view controller (e.g.
shouldAutorotateToInterfaceOrientation). There are cases where the interface may rotate without these methods being called, leaving the view controller's subviews in an inconsistent state.
If the app only supports iOS 5 or later, you should place layout code in the view controller's
If the app must support iOS 4, you should place layout code in the
layoutSubviewsmethod of the view controller's view.
Document Revision History
Updated to include changes to autorotation in iOS 6.
Added the case of not calling super on -(id)init.
New document that describes situations that can prevent view controllers from rotating.