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

后端 未结 16 2070
梦谈多话
梦谈多话 2020-11-22 12:07

Since my app got support for all orientation. I would like to lock only portrait mode to specific UIViewController.

e.g. assume it was Tabbed Application and when Si

16条回答
  •  花落未央
    2020-11-22 12:39

    A bunch of great answers in this thread, but none quite matched my needs. I have a tabbed app with navigation controllers in each tab, and one view needed to rotate, while the others needed to be locked in portrait. The navigation controller wasn't resizing it's subviews properly, for some reason. Found a solution (in Swift 3) by combining with this answer, and the layout issues disappeared. Create the struct as suggest by @bmjohns:

    import UIKit
    
    struct OrientationLock {
    
        static func lock(to orientation: UIInterfaceOrientationMask) {
            if let delegate = UIApplication.shared.delegate as? AppDelegate {
                delegate.orientationLock = orientation
            }
        }
    
        static func lock(to orientation: UIInterfaceOrientationMask, andRotateTo rotateOrientation: UIInterfaceOrientation) {
            self.lock(to: orientation)
            UIDevice.current.setValue(rotateOrientation.rawValue, forKey: "orientation")
        }
    } 
    

    Then subclass UITabBarController:

        import UIKit
    
    class TabBarController: UITabBarController, UITabBarControllerDelegate {
        required init?(coder aDecoder: NSCoder) {
            super.init(coder: aDecoder)
            self.delegate = self
        }
    
        func tabBarControllerSupportedInterfaceOrientations(_ tabBarController: UITabBarController) -> UIInterfaceOrientationMask {
            if tabBarController.selectedViewController is MyViewControllerNotInANavigationControllerThatShouldRotate {
                return .allButUpsideDown
            } else if let navController = tabBarController.selectedViewController as? UINavigationController, navController.topViewController is MyViewControllerInANavControllerThatShouldRotate {
                return .allButUpsideDown
            } else {
                //Lock view that should not be able to rotate
                return .portrait
            }
        }
    
        func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool {
            if viewController is MyViewControllerNotInANavigationControllerThatShouldRotate {
                OrientationLock.lock(to: .allButUpsideDown)
            } else if let navController = viewController as? UINavigationController, navController.topViewController is MyViewControllerInANavigationControllerThatShouldRotate {
                OrientationLock.lock(to: .allButUpsideDown)
            } else {
                //Lock orientation and rotate to desired orientation
                OrientationLock.lock(to: .portrait, andRotateTo: .portrait)
            }
            return true
        }
    }
    

    Don't forget to change the class of the TabBarController in the storyboard to the newly created subclass.

提交回复
热议问题