iosswiftuideviceorientation

Locking device orientation on a view fails when going back in NavBar


I have an app with several VCs embedded in a NavigationController.

I need all VCs to be locked in a portrait orientation and only one in both portrait and landscape.

I've tried different approaches and this one is working for me:

extension UINavigationController {
public override func supportedInterfaceOrientations() -> Int {
return visibleViewController.supportedInterfaceOrientations()
}
public override func shouldAutorotate() -> Bool {
return visibleViewController.shouldAutorotate()
}

}

And then I modify each ViewController like this:

class ViewController: UIViewController {
override func supportedInterfaceOrientations() -> Int {
return Int(UIInterfaceOrientationMask.Portrait.rawValue)
}

}

All is well when I open the app and go from one VC to another. The views that should be only Portrait are only Portrait. Then I open the view that wasn't modified and it changes the interfaceOrientation as intended.

BUT then let's say I leave the last unmodified view in Landscape and I press a back button in NavBar and go to the previous controller (which was modified to be only Portrait). The layout of the VC is shown as Landscape.

And if I keep pressing back button, all other VC behave like they were never told to be only portrait.

I used this post Korey Hinton, Lock Screen Rotation


Solution

  • I think I was able to replicate the scenario you described. Unfortunately the normal ways I try to force it to update didn't work but I did find this SO answer that seems to work. Put this in the view controller you return back to in viewDidAppear:

    override func viewDidAppear(animated: Bool) {
        super.viewDidAppear(animated)
    
        let value = UIInterfaceOrientation.Portrait.rawValue
        UIDevice.currentDevice().setValue(value, forKey: "orientation")
    }
    

    This fix seemed to work for me. It is a pretty rough transition though. I hope that helps