来回切换时锁定 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 被锁定为纵向。
我有一个简单的相机应用程序。 相机预览屏幕是 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 被锁定为纵向。