Swift5,先锁定VC竖屏模式,其他VC支持所有方向
Swift 5, lock first VC to Potrait mode, other VC support all orientations
我正在尝试在 Swift 5 中构建一个应用程序,该应用程序在 potrait 模式下已锁定 VC。在接下来的 VC 中,我希望方向能够支持所有方向。我尝试了几种不同的解决方案,其中 none 似乎有效。我没有导航控制器或 TabBar。我的应用程序现在在 VC:s 上都被锁定在 potrait 中。我在常规设置选项卡中支持不同的设备方向。
这是我在 AppDelegate 中的当前代码:
func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
return UIInterfaceOrientationMask.all
}
第一个VC:
override var shouldAutorotate: Bool {
return false
}
override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
return UIInterfaceOrientationMask.portrait
}
override var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation {
return UIInterfaceOrientation.portrait
}
第二个VC:
override var shouldAutorotate: Bool {
return false
}
override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
return UIInterfaceOrientationMask.all
}
1、首先在Info.plist.
启用所有方向
2、在任何地方创建协议
protocol RotatableViewController {
// No content necessary, marker protocol
}
3,将此添加到 Appdelegate:
extension AppDelegate {
func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
guard let rootVc = self.topViewControllerWithRootViewController(rootViewController: window?.rootViewController), rootVc.isBeingDismissed == false, let _ = rootVc as? RotatableViewController else { return .portrait } //swiftlint:disable:this all
return .allButUpsideDown
}
private func topViewControllerWithRootViewController(rootViewController: UIViewController!) -> UIViewController? {
if rootViewController == nil {
return nil
}
if rootViewController.isKind(of: UITabBarController.self) {
guard let root = rootViewController as? UITabBarController else { return UITabBarController() }
return topViewControllerWithRootViewController(rootViewController: root.selectedViewController)
} else if rootViewController.isKind(of: UINavigationController.self) {
guard let root = rootViewController as? UINavigationController else { return UINavigationController() }
return topViewControllerWithRootViewController(rootViewController: root.visibleViewController)
} else if rootViewController.presentedViewController != nil {
return topViewControllerWithRootViewController(rootViewController: rootViewController.presentedViewController)
}
return rootViewController
}
}
4、将RotatableViewController添加到你的控制器中,在你想要启用旋转的地方。
class ViewController: UIViewController, RotatableViewController
您是否在 Info.plist 中添加了 UISupportedInterfaceOrientations
声明?
您可以在目标配置面板中开启它:
接下来,删除 AppDelegate 中的 application(_:supportedInterfaceOrientationsFor:)
方法。只需在您的视图控制器中声明它们。
不幸的是,这是一个棘手的问题。但是如果你没有 UINavigationController
或 UITabBarController
它应该很简单。
在 AppDelegate
中,就像您已经完成的那样,输入:
func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
.all
}
在第一个 UIViewController 集合中:
// This stops the controller from rotating
override var shouldAutorotate: Bool {
false
}
// This will rotate it back to portrait once it's presented again
override var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation {
.portrait
}
在第二个中你不需要任何东西,因为 shouldAutorotate
默认为 true
。
注意:如果您没有使用 UINavigationController
,您可能正在使用第二个控制器。第二个控制器 必须有 一个 .fullScreen
或 .currentContext
的 modalPresentationStyle
。
我在一个示例项目中尝试过它,这是我让它工作的唯一方法。
步骤1:
在您的项目中添加以下代码。
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()
}
}
第 2 步:
在 AppDelegate class.
中添加以下代码
var orientationLock = UIInterfaceOrientationMask.all
func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
return self.orientationLock
}
第 3 步:
在第一个视图控制器中添加以下代码以锁定纵向方向。
override func viewWillAppear(_ animated: Bool) {
AppUtility.lockOrientation(.portrait, andRotateTo: .portrait)
}
override func viewWillDisappear(_ animated: Bool) {
//When controller Disappear unlock all orientation for other controllers.
AppUtility.lockOrientation(.all)
}
您可以像这样添加一些实用程序
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")
UINavigationController.attemptRotationToDeviceOrientation()
}
并分别在 view_willappear 和 view_willdisappear 上这样称呼它
Utility.lockOrientation(.portrait, andRotateTo: .portrait)
在 AppDelegate 中 return 下面委托方法中的 orientationlock 值
var orientationLock = UIInterfaceOrientationMask.all
func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
return orientationLock
}
对于Swift4、5+
只需在您的 ViewController
:
中添加这一行
public override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
return UIInterfaceOrientationMask.all
}
仅限 Portrait
:
public override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
return UIInterfaceOrientationMask.portrait
}
对于Landscape
:
public override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
return UIInterfaceOrientationMask.landscape
}
或者可以设置landscapeLeft
,landscapeRight
希望对你有用。
我正在尝试在 Swift 5 中构建一个应用程序,该应用程序在 potrait 模式下已锁定 VC。在接下来的 VC 中,我希望方向能够支持所有方向。我尝试了几种不同的解决方案,其中 none 似乎有效。我没有导航控制器或 TabBar。我的应用程序现在在 VC:s 上都被锁定在 potrait 中。我在常规设置选项卡中支持不同的设备方向。
这是我在 AppDelegate 中的当前代码:
func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
return UIInterfaceOrientationMask.all
}
第一个VC:
override var shouldAutorotate: Bool {
return false
}
override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
return UIInterfaceOrientationMask.portrait
}
override var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation {
return UIInterfaceOrientation.portrait
}
第二个VC:
override var shouldAutorotate: Bool {
return false
}
override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
return UIInterfaceOrientationMask.all
}
1、首先在Info.plist.
启用所有方向2、在任何地方创建协议
protocol RotatableViewController {
// No content necessary, marker protocol
}
3,将此添加到 Appdelegate:
extension AppDelegate {
func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
guard let rootVc = self.topViewControllerWithRootViewController(rootViewController: window?.rootViewController), rootVc.isBeingDismissed == false, let _ = rootVc as? RotatableViewController else { return .portrait } //swiftlint:disable:this all
return .allButUpsideDown
}
private func topViewControllerWithRootViewController(rootViewController: UIViewController!) -> UIViewController? {
if rootViewController == nil {
return nil
}
if rootViewController.isKind(of: UITabBarController.self) {
guard let root = rootViewController as? UITabBarController else { return UITabBarController() }
return topViewControllerWithRootViewController(rootViewController: root.selectedViewController)
} else if rootViewController.isKind(of: UINavigationController.self) {
guard let root = rootViewController as? UINavigationController else { return UINavigationController() }
return topViewControllerWithRootViewController(rootViewController: root.visibleViewController)
} else if rootViewController.presentedViewController != nil {
return topViewControllerWithRootViewController(rootViewController: rootViewController.presentedViewController)
}
return rootViewController
}
}
4、将RotatableViewController添加到你的控制器中,在你想要启用旋转的地方。
class ViewController: UIViewController, RotatableViewController
您是否在 Info.plist 中添加了 UISupportedInterfaceOrientations
声明?
您可以在目标配置面板中开启它:
接下来,删除 AppDelegate 中的 application(_:supportedInterfaceOrientationsFor:)
方法。只需在您的视图控制器中声明它们。
不幸的是,这是一个棘手的问题。但是如果你没有 UINavigationController
或 UITabBarController
它应该很简单。
在 AppDelegate
中,就像您已经完成的那样,输入:
func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
.all
}
在第一个 UIViewController 集合中:
// This stops the controller from rotating
override var shouldAutorotate: Bool {
false
}
// This will rotate it back to portrait once it's presented again
override var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation {
.portrait
}
在第二个中你不需要任何东西,因为 shouldAutorotate
默认为 true
。
注意:如果您没有使用 UINavigationController
,您可能正在使用第二个控制器。第二个控制器 必须有 一个 .fullScreen
或 .currentContext
的 modalPresentationStyle
。
我在一个示例项目中尝试过它,这是我让它工作的唯一方法。
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()
}
}
第 2 步: 在 AppDelegate class.
中添加以下代码var orientationLock = UIInterfaceOrientationMask.all
func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
return self.orientationLock
}
第 3 步: 在第一个视图控制器中添加以下代码以锁定纵向方向。
override func viewWillAppear(_ animated: Bool) {
AppUtility.lockOrientation(.portrait, andRotateTo: .portrait)
}
override func viewWillDisappear(_ animated: Bool) {
//When controller Disappear unlock all orientation for other controllers.
AppUtility.lockOrientation(.all)
}
您可以像这样添加一些实用程序
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")
UINavigationController.attemptRotationToDeviceOrientation()
}
并分别在 view_willappear 和 view_willdisappear 上这样称呼它
Utility.lockOrientation(.portrait, andRotateTo: .portrait)
在 AppDelegate 中 return 下面委托方法中的 orientationlock 值
var orientationLock = UIInterfaceOrientationMask.all
func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
return orientationLock
}
对于Swift4、5+
只需在您的 ViewController
:
public override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
return UIInterfaceOrientationMask.all
}
仅限 Portrait
:
public override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
return UIInterfaceOrientationMask.portrait
}
对于Landscape
:
public override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
return UIInterfaceOrientationMask.landscape
}
或者可以设置landscapeLeft
,landscapeRight
希望对你有用。