Changing the orientation of a UITabBarController
While there are dozens of maybe and try this for this problem, the main issue reside in the careful design of each UINavigationController
, a proper response to supportedInterfaceOrientations
in the UITabBarController
, and some code to enforce the desired orientation.
In all likelihood, this may just be an iOS bug, since once rotated, the UINavBarController
and all embedded UINavigationController
behave correctly.
The following statement is not true. Tab bar controllers do rotate.
TabBarControllers can't rotate
Setup orientation for each UINavigationController
Landscape example:
class HorizontalNavigationController: UINavigationController {
override var supportedInterfaceOrientations : UIInterfaceOrientationMask {
return .landscape
}
}
Portrait example:
class VerticalNavigationController: UINavigationController {
override var supportedInterfaceOrientations : UIInterfaceOrientationMask {
return .portrait
}
}
Defer TabBarController
orientation to selected view controller
class TabBarController: UITabBarController {
override var supportedInterfaceOrientations : UIInterfaceOrientationMask {
if let selectedViewController = selectedViewController {
return selectedViewController.supportedInterfaceOrientations
}
return .allButUpsideDown
}
}
Enforce the interface orientation change
This is the contentious aspect of UITabBarController
. Somehow, the orientation change does not happen like it would in a UINavigationController
, and needs a nudge.
To do so with the fewest amount of code, use an Object and subclass it into a TabBarControllerDelegate
. You can do most of the work in Interface Builder.
class TabBarControllerDelegate: NSObject, UITabBarControllerDelegate {
func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) {
let orientedViewController = UIViewController()
tabBarController.present(orientedViewController, animated: false) { () -> Void in
tabBarController.dismiss(animated: false, completion: { () -> Void in
})
}
}
}
Storyboard Structure
Using a Storyboard
helps visualize the structure of the application as well as the relationship between all classes.
? Find this solution on GitHub and additional details on Swift Recipes.