This is a common question on StackOverflow, but none of the other solutions worked. Many were also written several years ago.
Here are some of the posts considered:<
Subclass UINavigationController
.
class LandscapeNavigationController: UINavigationController {
public var vertical: Bool = true
override var shouldAutorotate: Bool {
get { return true }}
override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
get { return (vertical) ? .portrait : .landscapeLeft }}
override var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation {
get { return (vertical) ? .portrait : .landscapeLeft }}
}
Use different UINavigationController
for different orientations. Yes, pushing a new UINavigationController
atop a previous UINavigationController
will essentially be modal, but the transition looks nice.
For added convenience, use User Defined Runtime Attributes to control the orientation of the LandscapeNavigationController
.
Add a pop method to handle Back buttons on the now modal UIViewController
.
@IBAction func doBack(_ sender: UIBarButtonItem) {
if let navigationController = navigationController {
navigationController.dismiss(animated: true, completion: {
})
}
}
Notice how the Top and Bottom labels on view C are properly laid out.
↻ replay animation
► Find this solution on GitHub and additional details on Swift Recipes.