How to lock orientation of one view controller to portrait mode only in Swift How to lock orientation of one view controller to portrait mode only in Swift swift swift

How to lock orientation of one view controller to portrait mode only in Swift


Things can get quite messy when you have a complicated view hierarchy, like having multiple navigation controllers and/or tab view controllers.

This implementation puts it on the individual view controllers to set when they would like to lock orientations, instead of relying on the App Delegate to find them by iterating through subviews.

Swift 3, 4, 5

In AppDelegate:

/// set orientations you want to be allowed in this property by defaultvar orientationLock = UIInterfaceOrientationMask.allfunc application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {        return self.orientationLock}

In some other global struct or helper class, here I created AppUtility:

struct AppUtility {    static func lockOrientation(_ orientation: UIInterfaceOrientationMask) {            if let delegate = UIApplication.shared.delegate as? AppDelegate {            delegate.orientationLock = orientation        }    }    /// OPTIONAL Added method to adjust lock and rotate to the desired orientation    static func lockOrientation(_ orientation: UIInterfaceOrientationMask, andRotateTo rotateOrientation:UIInterfaceOrientation) {           self.lockOrientation(orientation)            UIDevice.current.setValue(rotateOrientation.rawValue, forKey: "orientation")        UINavigationController.attemptRotationToDeviceOrientation()    }}

Then in the desired ViewController you want to lock orientations:

 override func viewWillAppear(_ animated: Bool) {    super.viewWillAppear(animated)        AppUtility.lockOrientation(.portrait)    // Or to rotate and lock    // AppUtility.lockOrientation(.portrait, andRotateTo: .portrait)    }override func viewWillDisappear(_ animated: Bool) {    super.viewWillDisappear(animated)        // Don't forget to reset when view is being removed    AppUtility.lockOrientation(.all)}

If iPad or Universal App

Make sure that "Requires full screen" is checked in Target Settings -> General -> Deployment Info. supportedInterfaceOrientationsFor delegate will not get called if that is not checked.enter image description here


Swift 4

enter image description hereAppDelegate

var orientationLock = UIInterfaceOrientationMask.allfunc application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {    return self.orientationLock}struct AppUtility {    static func lockOrientation(_ orientation: UIInterfaceOrientationMask) {        if let delegate = UIApplication.shared.delegate as? AppDelegate {            delegate.orientationLock = orientation        }    }    static func lockOrientation(_ orientation: UIInterfaceOrientationMask, andRotateTo rotateOrientation:UIInterfaceOrientation) {        self.lockOrientation(orientation)        UIDevice.current.setValue(rotateOrientation.rawValue, forKey: "orientation")    }}

Your ViewControllerAdd Following line if you need only portrait orientation. you have to apply this to all ViewController need to display portrait mode.

override func viewWillAppear(_ animated: Bool) {AppDelegate.AppUtility.lockOrientation(UIInterfaceOrientationMask.portrait, andRotateTo: UIInterfaceOrientation.portrait)    }

andthat will make screen orientation for others Viewcontroller according to device physical orientation.

override func viewWillDisappear(_ animated: Bool) {        AppDelegate.AppUtility.lockOrientation(UIInterfaceOrientationMask.all)    }


Swift 3 & 4

Set the supportedInterfaceOrientations property of specific UIViewControllers like this:

class MyViewController: UIViewController {    var orientations = UIInterfaceOrientationMask.portrait //or what orientation you want    override var supportedInterfaceOrientations : UIInterfaceOrientationMask {    get { return self.orientations }    set { self.orientations = newValue }    }    override func viewDidLoad() {        super.viewDidLoad()    }    //...}

UPDATE

This solution only works when your viewController is not embedded in UINavigationController, because the orientation inherits from parent viewController.
For this case, you can create a subclass of UINavigationViewController and set these properties on it.