仅在一个ViewController中旋转

我试图旋转一个视图,而所有其他视图(5)固定为肖像。 原因在于,在这种观点中,我希望用户观看他以前保存的照片。 我想这是可能的,但到目前为止我无法弄清楚如何实现这一目标。 任何人都可以帮助或给我一个提示? 我在iOS8上运行Swift编程

我build议在你的appDelegate使用supportedInterfaceOrientationsForWindow只允许在特定的视图控制器中旋转,例如:

Swift 3 <

 func application(application: UIApplication, supportedInterfaceOrientationsForWindow window: UIWindow?) -> Int { // Make sure the root controller has been set // (won't initially be set when the app is launched) if let navigationController = self.window?.rootViewController as? UINavigationController { // If the visible view controller is the // view controller you'd like to rotate, allow // that window to support all orientations if navigationController.visibleViewController is SpecificViewController { return Int(UIInterfaceOrientationMask.All.rawValue) } // Else only allow the window to support portrait orientation else { return Int(UIInterfaceOrientationMask.Portrait.rawValue) } } // If the root view controller hasn't been set yet, just // return anything return Int(UIInterfaceOrientationMask.Portrait.rawValue) } 

请注意,如果在转到纵向屏幕之前,该SpecificViewController处于横向模式,则其他视图仍将横向打开。 为了规避这个问题,我build议不要在转换过程中考虑风景。

斯威夫特4

 func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask { if let navigationController = self.window?.rootViewController as? UINavigationController { if navigationController.visibleViewController is DetailsTableViewController { return UIInterfaceOrientationMask.all } else { return UIInterfaceOrientationMask.portrait } } return UIInterfaceOrientationMask.portrait } 

要在横向和纵向模式下显示的ViewController中使用shouldAutorotatesupportedInterfaceOrientations方法:

这种方法应该覆盖故事板设置。

 override func shouldAutorotate() -> Bool { return true } override func supportedInterfaceOrientations() -> Int { return UIInterfaceOrientation.Portrait.rawValue | UIInterfaceOrientation.LandscapeLeft.rawValue | UIInterfaceOrientation.LandscapeRight.rawValue } 

我只是面对一个非常类似的问题,我想以纵向和横向模式呈现video播放器,而应用程序的其余部分只是纵向显示。 我的主要问题是,当我在景观模式下解除videovc时,呈现vc只是简单地在横向模式下。
正如在@Lyndsey Scott的回答中所指出的那样,在横向模式下,可以通过禁止转换来绕过这个问题,但是通过结合这 一点,我发现了一个更好更通用的解决scheme(IMO)。 这个解决scheme允许在你放置canRotate(){}所有vc中旋转,并且不会旋转呈现的vc。

Swift 3:
在AppDelegate.swift中:

 func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask { if let rootViewController = self.topViewControllerWithRootViewController(rootViewController: window?.rootViewController) { if (rootViewController.responds(to: Selector(("canRotate")))) { // Unlock landscape view orientations for this view controller if it is not currently being dismissed if !rootViewController.isBeingDismissed{ return .allButUpsideDown } } } // Only allow portrait (standard behaviour) return .portrait } private func topViewControllerWithRootViewController(rootViewController: UIViewController!) -> UIViewController? { if (rootViewController == nil) { return nil } if (rootViewController.isKind(of: UITabBarController.self)) { return topViewControllerWithRootViewController(rootViewController: (rootViewController as! UITabBarController).selectedViewController) } else if (rootViewController.isKind(of: UINavigationController.self)) { return topViewControllerWithRootViewController(rootViewController: (rootViewController as! UINavigationController).visibleViewController) } else if (rootViewController.presentedViewController != nil) { return topViewControllerWithRootViewController(rootViewController: rootViewController.presentedViewController) } return rootViewController } 

在允许旋转的每个视图控制器中:

 func canRotate(){} 

你也可以用面向协议的方式来做到这一点。 只需创build协议

 protocol CanRotate { } 

以更“快捷”的方式在AppDelegate中添加相同的2个方法

 func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask { if topViewController(in: window?.rootViewController) is CanRotate { return .allButUpsideDown } else { return .portrait } } func topViewController(in rootViewController: UIViewController?) -> UIViewController? { guard let rootViewController = rootViewController else { return nil } if let tabBarController = rootViewController as? UITabBarController { return topViewController(in: tabBarController.selectedViewController) } else if let navigationController = rootViewController as? UINavigationController { return topViewController(in: navigationController.visibleViewController) } else if let presentedViewController = rootViewController.presentedViewController { return topViewController(in: presentedViewController) } return rootViewController } 

在每个ViewController中你想要一个不同的行为,只需要在类的定义中添加协议名称即可。

 class ViewController: UIViewController, CanRotate {} 

如果你想要任何特定的组合,他们可以添加到协议的variables来覆盖

 protocol CanRotate { var supportedInterfaceOrientations: UIInterfaceOrientationMask } 

Swift 3:将代码添加到AppDelegate.swift

 func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask { if let rootViewController = self.topViewControllerWithRootViewController(rootViewController: window?.rootViewController) { if (rootViewController.responds(to: Selector(("canRotate")))) { // Unlock landscape view orientations for this view controller return .allButUpsideDown; } } // Only allow portrait (standard behaviour) return .portrait; } private func topViewControllerWithRootViewController(rootViewController: UIViewController!) -> UIViewController? { if (rootViewController == nil) { return nil } if (rootViewController.isKind(of: (UITabBarController).self)) { return topViewControllerWithRootViewController(rootViewController: (rootViewController as! UITabBarController).selectedViewController) } else if (rootViewController.isKind(of:(UINavigationController).self)) { return topViewControllerWithRootViewController(rootViewController: (rootViewController as! UINavigationController).visibleViewController) } else if (rootViewController.presentedViewController != nil) { return topViewControllerWithRootViewController(rootViewController: rootViewController.presentedViewController) } return rootViewController } 

然后 :

 import UIKit class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() } override func viewWillDisappear(_ animated : Bool) { super.viewWillDisappear(animated) if (self.isMovingFromParentViewController) { UIDevice.current.setValue(Int(UIInterfaceOrientation.portrait.rawValue), forKey: "orientation") } } func canRotate() -> Void {} } 

http://www.jairobjunior.com/blog/2016/03/05/how-to-rotate-only-one-view-controller-to-landscape-in​​-ios-slash-swift/

SWIFT 4

对于UITabBarController ,我们可以在AppDelegate.swift使用这一行代码。

 func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask { if let tabBarController = window?.rootViewController as? UITabBarController { if let tabBarViewControllers = tabBarController.viewControllers { if let projectsNavigationController = tabBarViewControllers[1] as? UINavigationController { if projectsNavigationController.visibleViewController is PickerViewController //use here your own ViewController class name { return .all } } } } return .portrait }