UITabBarController和UINavigationController中的特定UIViewController中的设备旋转

基本上,这是我的页面结构,其中:

TBC = UITabBarController; VC = UIViewController; NVC = UINavigationViewController

  +--> [NVC] --> [VC] --> ... --> [VC] Home | [VC] --> [TBC] --+--> [NVC] --> [VC] --> ... --> [VC] | +--> [NVC] --> [VC] --> ... --> [VC] 

我希望一些具体的VC可以被允许在不同的方向上查看。 最可能的是,这些将是叶节点VC 。 这可能是显示图片或其他内容的页面。

大部分的应用程序只能以纵向浏览。 想想Facebook应用程序,其中大多数核心页面都是以纵向浏览的,而图片/video可以纵向或横向浏览。

我从这个答案基于我的解决scheme。

AppDelegate.swift

 func application (application: UIApplication, supportedInterfaceOrientationsForWindow window: UIWindow?) -> UIInterfaceOrientationMask { return checkOrientation(self.window?.rootViewController) } 

checkOrientationfunction:

 func checkOrientation (viewController: UIViewController?) -> UIInterfaceOrientationMask { if viewController == nil { return UIInterfaceOrientationMask.Portrait } else if viewController is MyViewController { return UIInterfaceOrientationMask.AllButUpsideDown } else if viewController is MyTabBarController { if let tabBarController = viewController as? MyTabBarController, navigationViewControllers = tabBarController.viewControllers as? [MyNavigationController] { return checkOrientation(navigationViewControllers[tabBarController.selectedIndex].visibleViewController) } else { return UIInterfaceOrientationMask.Portrait } } else { return checkOrientation(viewController!.presentedViewController) } } 

逻辑与if/else和recursion可以改善,但它现在工作。

如果必须强制上一个/下一个UIViewController的方向,则应将此行添加到当前的UIViewControllerviewWillDisappear方法中。 这将强制上一个/下一个视图

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

如果有复杂的视图层次结构(如具有多个导航控制器和/或选项卡视图控制器),事情会变得相当混乱。

这个实现把它放在每个视图控制器上,以便当他们想要locking方向时,而不是依靠应用程序委托来find它们。

Swift 3

在AppDelegate中:

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

在其他一些全局结构体或帮助器类中,我在这里创build了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") } } 

然后在所需的ViewController中,您要locking方向:

  override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(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) }