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

Posted

技术标签:

【中文标题】来回切换时锁定的 ViewController 方向中断【英文标题】:Locked ViewController orientation breaking when segueing back and forth 【发布时间】:2018-08-11 21:59:58 【问题描述】:

我有一个简单的相机应用程序。 相机预览屏幕是一个视图控制器(名称 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 方向,这是我想要的。 但是,如果我点击库按钮,这会将我转到另一个屏幕, 并通过旋转我的物理设备更改库屏幕的方向,然后通过“返回”按钮返回我的相机预览屏幕,方向被破坏。它处于横向模式,而不是纵向模式。 如何获得硬锁?

以防万一,我在这里做了一个我的代码的虚拟模型(这里太长了,不能在这里发布),你们可以自己测试一下

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。

【问题讨论】:

你的项目崩溃了 @Vyacheslav 请尝试再运行一次。由于某种原因,第一次运行应用程序时它会崩溃。谢谢。 【参考方案1】:

你犯了两个错误。

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

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

【讨论】:

谢谢。我无法将 ViewController 正确设置为导航控制器的委托。在 EDIT2 下查看我在 OP 中的尝试。我会很感激你教我如何正确地做到这一点。我在网上找不到任何关于导航控制器如何正确执行此操作的示例。谢谢。 @Moondra developer.apple.com/documentation/uikit/uiviewcontroller/… 我已经查看了文档:developer.apple.com/documentation/uikit/uiviewcontroller/…developer.apple.com/documentation/uikit/…developer.apple.com/documentation/uikit/… 这就是我能够得到上面示例的方式。但是,我在文档中看不到任何示例,因此我无法理解如何使其正常工作。谢谢。 所以文档不足以让您制定短语self.navigationController?.delegate = self 我查看了文档,但无法弄清楚。我什至根据你所说的给出了一个我试图做的工作示例。请原谅我的居高临下的态度。【参考方案2】:

我也无法运行您的应用。但我在 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 被锁定为纵向。

【讨论】:

谢谢。当您说“然后在允许 allButUpsideDown 的应用程序中(或将其更改为您想要的)时,您添加以下代码”,您的意思是视图控制器而不是“应用程序”。这是否意味着我必须添加我不想锁定的每个视图控制器?要去测试一下。至于应用程序崩溃,它总是第一次崩溃,但第二次通常没问题。这是我最终必须解决的另一个错误。 很好地抓住了需要成为“VC”的“应用程序”。我编辑了这个。而且,是的,您需要将此代码添加到每个违反应用程序委托设置的 VC(在此示例中,对于所有方向都是错误的,并且仅设置为纵向) 这很好用。我刚刚将var enableAllOrientation = false 切换为true,所以我只需要更改一个视图控制器。

以上是关于来回切换时锁定的 ViewController 方向中断的主要内容,如果未能解决你的问题,请参考以下文章

将 2 个 ViewController 组合在 TabBarView 的单个选项卡中,并允许在同一选项卡内来回切换

“未能锁定”错误

在视图控制器之间来回切换

使用自定义 Segue 快速切换到和 FromTable ViewController 问题

Swift viewcontroller firebase 数据库观察者重复调用

如何在启动应用程序时锁定方向并在导航到 Viewcontroller 时解锁它