如何通过陀螺仪强制iOS设备确定其方向?

时间:2018-09-04 18:58:09

标签: ios swift uiviewcontroller

我遇到这样的情况,我的应用有时会强制特定的视图控制器以特定的方向出现。

我发现这样做的唯一方法是手动设置设备方向,并告诉应用尝试像这样旋转自身:

colsumsum2

这很好用。但是,一旦我关闭了该视图控制器,并返回到前一个控制器,无论如何握住设备,我仍然处于强制方向。有没有一种方法可以将方向值设置为“ dirty”或其他值并使其自动检测?

我尝试将方向值设置为0,然后尝试旋转,但这不起作用。

我正在使用Swift 4.1

-编辑-

为了澄清我在做什么,

在创建我的视图控制器时,它会将自己设置为根视图控制器(这样它的旋转设置才能真正起作用,否则将使用根行为)在初始化过程中的某个时刻,可以告诉它应该以特定方式定位。如果是这样,则执行上面的代码,并适当地设置它的方向蒙版。我正在使用这些替代:

switch (forceOrientation){
    case Orientations.PORTRAIT:
        let value = UIInterfaceOrientation.portrait.rawValue
        UIDevice.current.setValue(value, forKey: "orientation")
        UIViewController.attemptRotationToDeviceOrientation()
    case Orientations.LANDSCAPE:
        let value = UIInterfaceOrientation.landscapeLeft.rawValue
        UIDevice.current.setValue(value, forKey: "orientation")
        UIViewController.attemptRotationToDeviceOrientation()
    default:
        break
}

关闭视图控制器时,以前的根控制器将重新添加为根。 (但是它仍然会旋转到强制使用的位置,除非您四处移动设备,否则它不会更新)

1 个答案:

答案 0 :(得分:0)

您可以覆盖var supportedInterfaceOrientations: UIInterfaceOrientationMask { get }并对其进行设置,以使其在任何给定时间返回所需的可用方向。

基本上,让此属性返回与您的forceOrientation枚举相关的变量。

有关详细信息,请参见https://developer.apple.com/documentation/uikit/uiviewcontroller/1621435-supportedinterfaceorientations

要强制旋转,可以执行以下操作:

let previousOrientation = UIDevice.current.orientation  
let value = UIInterfaceOrientation.landscapeLeft.rawValue
UIDevice.current.setValue(value, forKey: "orientation")
//Rotates all view controllers
UIViewController.attemptRotationToDeviceOrientation()

//Find all UIViewControllers that need to be locked,  I recommend using a protocol


guard let appDelegate = UIApplication.sharedApplication().delegate, 
      let window = appDelegate.window, 
      let root = window.rootViewController,


else{
    fatalError("error")
} 
var viewControllers : [UIViewController] = []()
if root.presentedViewController != nil {
    viewControllers += [root.presentedViewController]
}
viewControllers += root.children
viewControllers.filter{$0 as OrientationLocked}.forEach{ vc in
  vc.orientationMask = ... //whatever previousOrientation isn't
}

//undo rotation
UIDevice.current.setValue(previousOrientation, forKey: "orientation")
UIViewController.attemptRotationToDeviceOrientation()

//View controllers that had been filtered are now rotated, where as anything underneath were treated as if a rotation did not happen

...     任何可以锁定的视图控制器都需要此协议

protocol OrientationLocked {
    var orientationMask : UIInterfaceOrientationMask 
}