来回切换时锁定 ViewController 方向中断

Locked ViewController orientation breaking when segueing back and forth

我有一个简单的相机应用程序。 相机预览屏幕是 viewcontroller(名称 ViewController),我通过它锁定了方向 此代码(找不到此代码的 Whosebug link),viewcontroller 嵌入在导航控制器中:

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

当相机启动时,相机预览锁定在.portrait 方向,这是我想要的。 但是,如果我点击库按钮,它会将我转到另一个屏幕, 并通过旋转我的物理设备来更改库屏幕的方向,然后通过 "back" 按钮 return 回到我的相机预览屏幕,方向被破坏了。它处于横向模式,而不是纵向模式。 我如何获得硬锁?

以防万一,我在这里制作了一个我的代码的虚拟模型(这里太长 post),你们可以自己测试一下

https://github.com/bigmit2011/Testing-Camera

编辑:

如果应用程序崩溃,请再试一次 运行。 由于某种原因,应用程序第一次 运行 崩溃。谢谢。

编辑2:

正在尝试将嵌入式 ViewController 设置为 UINavigationController 的委托。 但是,我不太明白我这样做是否正确:

class ViewController: UIViewController, UINavigationControllerDelegate {

    var navigation: UINavigationController?
    self.navigation.delegate = self  // doesn't seem to work


    func navigationControllerSupportedInterfaceOrientations(_ navigationController: UINavigationController) -> UIInterfaceOrientationMask {

        return .portrait
    }

我需要为 UiNavigationController 创建一个单独的 swift 文件吗?

编辑3: 以下是马特的回答代码如下:

class CameraViewController :UIViewController, UINavigationControllerDelegate {

override func viewDidLoad() {

    self.navigationController?.delegate = self
    super.viewDidLoad()

func navigationControllerSupportedInterfaceOrientations(_ navigationController: UINavigationController) -> UIInterfaceOrientationMask {

        return .portrait
    }

但是,这似乎将所有内容都锁定为纵向模式,而不仅仅是嵌入在导航控制器中的单个 viewController。

你犯了两个错误。

  • 首先,您试图从应用程序委托中控制各个视图控制器的方向。那是错误的。应用委托管理 整个 应用的 可能 方向的全部。但是对于视图控制器,每个单独的视图控制器都控制其 自己的 方向。只需在您的两个视图控制器(而不是在应用程序委托中)中的每一个中实现 supportedInterfaceOrientations

  • 其次,您的第一个视图控制器位于导航界面中。因此它不是顶级视图控制器并且不能直接控制方向(supportedInterfaceOrientations)。管理导航界面方向的正确方法是将自己设置为导航控制器的 delegate 并实现 navigationControllerSupportedInterfaceOrientations(_:).

我也不能 运行 你的应用程序。但是我在 Xcode 中用一个主 VC、第二个 VC 测试了这个,并将主 VC 嵌入了导航控制器。然后我遵循了这篇文章中的建议 Selective rotation lock in iOS

您将以下内容添加到 AppDelegate:

var enableAllOrientation = false

func application(_ application: UIApplication,supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
if (enableAllOrientation == true){
    return UIInterfaceOrientationMask.allButUpsideDown
}
return UIInterfaceOrientationMask.portrait
}

然后在允许 allButUpsideDown 的 VC 中(或将其更改为您想要的),添加以下代码:

override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
let appDelegate = UIApplication.shared.delegate as! AppDelegate
appDelegate.enableAllOrientation = true
}

override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)

let appDelegate = UIApplication.shared.delegate as! AppDelegate
appDelegate.enableAllOrientation = false

let value = UIInterfaceOrientation.portrait.rawValue
UIDevice.current.setValue(value, forKey: "orientation")
}

我把这个放在第二个VC。 运行 模拟器中的应用程序,转到第二个 VC,将方向更改为横向然后返回,主要 VC 被锁定为纵向。