Andreas Schweiger
Andreas Schweiger

Reputation: 67

UiViewController which supports Landscape Orientation puts other Views in Landscape

I searched now for a day an did not find a proper solution. My app consists of a Tab Bar Controller and Navigation Controllers inside. I want all screens only Portrait, but just one sub view been Landscape.

And it works to get there, but when I return from the subview staying in landscape orientation physically, the parent also is presented as landscape, despite the fact that I only permit .portrait ind the controller.

I already did:

extension UITabBarController {
   override open var shouldAutorotate: Bool {
      get {
          if let visibleVC = selectedViewController {
              return visibleVC.shouldAutorotate
          }
          return super.shouldAutorotate
      }
   }

   override open var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation{
       get {
           if let visibleVC = selectedViewController {
               return visibleVC.preferredInterfaceOrientationForPresentation
           }
           return super.preferredInterfaceOrientationForPresentation
       }
   }

   override open var supportedInterfaceOrientations: UIInterfaceOrientationMask {
      // your custom logic for rotation of selected tab
         get {
               if let visibleVC = selectedViewController {
                   return visibleVC.supportedInterfaceOrientations
               }
               return super.supportedInterfaceOrientations
           }
   }
}

extension UINavigationController {
   override open var shouldAutorotate: Bool {
       get {
           if let visibleVC = visibleViewController {
               return visibleVC.shouldAutorotate
           }
           return super.shouldAutorotate
       }
   }

   override open var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation{
       get {
           if let visibleVC = visibleViewController {
               return visibleVC.preferredInterfaceOrientationForPresentation
           }
           return super.preferredInterfaceOrientationForPresentation
       }
   }

   override open var supportedInterfaceOrientations: UIInterfaceOrientationMask{
       get {
           if let visibleVC = visibleViewController {
               return visibleVC.supportedInterfaceOrientations
           }
           return super.supportedInterfaceOrientations
       }
   }
} 

and in the parent controller:

  override var shouldAutorotate: Bool{
      return true
   }

   override var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation{
        return .portrait
   }

   override var supportedInterfaceOrientations: UIInterfaceOrientationMask{
      return .portrait
   }

When I turn the device then to Portrait the View is again displayed in Portrait, but I want that to happen immediately after the dismissal of the child in landscape, even if I don't turn the device.

Any ideas anybody? Thanks!

Upvotes: 0

Views: 37

Answers (1)

Gowri G
Gowri G

Reputation: 420

In Your landscape View controller add this code

override func viewDidLoad() {
    super.viewDidLoad()
let appDelegate = UIApplication.shared.delegate as! AppDelegate
    appDelegate.myOrientation = .landscapeRight
}

and ViewWillDisappear add this

override func viewWillDisappear(_ animated: Bool) {
    let appDelegate = UIApplication.shared.delegate as! AppDelegate
    appDelegate.myOrientation = .portrait
    UIView.setAnimationsEnabled(false)
    UIDevice.current.setValue(UIInterfaceOrientation.portrait.rawValue, forKey: "orientation")
    UIView.setAnimationsEnabled(true)
    UIViewController.attemptRotationToDeviceOrientation()
    UIView.setAnimationsEnabled(false)
}

In appDeledate add this line

var window: UIWindow?
var myOrientation: UIInterfaceOrientationMask = .portrait

Upvotes: 1

Related Questions