You can use the method supportedInterfaceOrientations()
in order to specify the orientation available for a specific view controller.
But, when your embed your view controllers in a navigation stack, the system calls shouldAutorotate
and supportedInterfaceOrientations
on your navigation controller, and the value returned from your view controllers are ignored.
I use a subclass of UINavigationController
in order to get the supported orientations from the top view controller. You can also created such a class for UITabBarViewController
class SingleOrientationNavigationController: UINavigationController {
//MARK : Orientation
override func shouldAutorotate() -> Bool {
if let topVC = topViewController {
return topVC.shouldAutorotate()
}
return false
}
override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
if let topVC = topViewController {
return topVC.supportedInterfaceOrientations()
}
return UIInterfaceOrientationMask.Portrait
}
// MARK : Status bar
override func preferredStatusBarStyle() -> UIStatusBarStyle {
if let topVC = topViewController {
return topVC.preferredStatusBarStyle()
}
return .Default
}
}
Be careful, you can have some issues if the pushed view controllers got less rotation option than the previous one.
Let's consider two view controllers :
A : only portrait
B : all orientation
If a push is performed from A to B, then it will be ok, B can be rotating as it desire, and even if B is in landscape when it will pop, you'll go back to A in portrait.
But if a push is performed from B to A while B is in landscape, then A will be displayed as landscape too ! One workaround is to use modal view controllers instead of pushing it in this special case.