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
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
I had this problem with presented view controllers and orientation lock differences. I added this into the "unlocked" controller:
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
[self willRotateToInterfaceOrientation:UIInterfaceOrientationLandscapeLeft duration:0];
}
So when that controller is about to be removed (back button pressed) it sends a message that it should return to landscape (it doesn't matter left or right because the pervious controller will autorotate from that to the proper orientation). That's in objective-c, but I'm sure there is an analogous operation in swift. You may have to mess with the animation duration if it makes things look weird, but mine worked perfectly with an immediate switch.
来源:https://stackoverflow.com/questions/30486133/locking-device-orientation-on-a-view-fails-when-going-back-in-navbar