【问题标题】:Get current iOS device orientation even if device's orientation locked即使设备的方向被锁定,也能获取当前的 iOS 设备方向
【发布时间】:2018-08-16 06:52:28
【问题描述】:

即使设备的方向被锁定,我也想获取当前的 iOS 设备方向。 (就像 iOS 相机应用一样)

我想至少检测纵向、横向左侧和横向右侧。

当方向锁定时,UIDeviceOrientation 和 UIInterfaceOrientation 似乎不起作用。

在这种情况下,我认为我们将使用 CoreMotion。

我如何在swift4中逻辑它?

【问题讨论】:

  • 你试过this answer吗?
  • 感谢您的回复。是的,但没有解决。即使将设备放在桌子上,方向也不稳定......
  • 对于 table 上的设备放置,您需要考虑z 轴。它没有在那个答案中完成,但留下了关于 face upface down 方向的线索。
  • 谢谢。我试试看。

标签: ios swift core-motion


【解决方案1】:

用核心运动声明运动管理器

    var orientationLast = UIInterfaceOrientation(rawValue: 0)!
    var motionManager: CMMotionManager?

运动管理器初始化

并在 viewDidLoad 中调用该函数

    func initializeMotionManager() {
     motionManager = CMMotionManager()
     motionManager?.accelerometerUpdateInterval = 0.2
     motionManager?.gyroUpdateInterval = 0.2
     motionManager?.startAccelerometerUpdates(to: (OperationQueue.current)!, withHandler: {
        (accelerometerData, error) -> Void in
        if error == nil {
            self.outputAccelertionData((accelerometerData?.acceleration)!)
        }
        else {
            print("\(error!)")
        }
        })
     }   

分析加速度计仪表数据

 func outputAccelertionData(_ acceleration: CMAcceleration) {
    var orientationNew: UIInterfaceOrientation
    if acceleration.x >= 0.75 {
        orientationNew = .landscapeLeft
        print("landscapeLeft")
    }
    else if acceleration.x <= -0.75 {
        orientationNew = .landscapeRight
        print("landscapeRight")
    }
    else if acceleration.y <= -0.75 {
        orientationNew = .portrait
        print("portrait")

    }
    else if acceleration.y >= 0.75 {
        orientationNew = .portraitUpsideDown
        print("portraitUpsideDown")
    }
    else {
        // Consider same as last time
        return
    }

    if orientationNew == orientationLast {
        return
    }
    orientationLast = orientationNew
}

【讨论】:

  • 按预期工作。谢谢!
  • 删除不必要的属性及其初始化。
  • NOICE!很好的答案
  • 摇滚明星!!谢谢!
  • 如何在整个应用中收听?
【解决方案2】:

斯威夫特 5

声明

var motionManager   : CMMotionManager!

初始化

func addCoreMotion() {

    let splitAngle:Double = 0.75
    let updateTimer:TimeInterval = 0.5

    motionManager = CMMotionManager()
    motionManager?.gyroUpdateInterval = updateTimer
    motionManager?.accelerometerUpdateInterval = updateTimer

    var orientationLast    = UIInterfaceOrientation(rawValue: 0)!

    motionManager?.startAccelerometerUpdates(to: (OperationQueue.current)!, withHandler: {
        (acceleroMeterData, error) -> Void in
        if error == nil {

            let acceleration = (acceleroMeterData?.acceleration)!
            var orientationNew = UIInterfaceOrientation(rawValue: 0)!

            if acceleration.x >= splitAngle {
                orientationNew = .landscapeLeft
            }
            else if acceleration.x <= -(splitAngle) {
                orientationNew = .landscapeRight
            }
            else if acceleration.y <= -(splitAngle) {
                orientationNew = .portrait
            }
            else if acceleration.y >= splitAngle {
                orientationNew = .portraitUpsideDown
            }

            if orientationNew != orientationLast && orientationNew != .unknown{
                orientationLast = orientationNew
                self.deviceOrientationChanged(orinetation: orientationNew)
            }
        }
        else {
            print("error : \(error!)")
        }
    })
}

结果

 func deviceOrientationChanged(orinetation:UIInterfaceOrientation) {

      print("orinetation :",orinetation.rawValue)
     // updatYourUI or another stuff

 }

【讨论】:

    【解决方案3】:

    以下是检测设备旋转并返回 UIDeviceOrientation 的示例。 此解决方案使用 CoreMotion,适用于所有情况。

    示例

    let orientationManager = APOrientationManager()
    orientationManager.delegate = self
    /// start detect rotation
    orientationManager.startMeasuring()
    
    /// get current interface orientation
    let orientation = orientationManager.currentInterfaceOrientation()
    print(orientation.rawValue)
    
    /// stop detect rotation
    orientationManager.stopMeasuring()
    orientationManager.delegate = nil
    

    符合委托

    extension ViewController: APOrientationManagerDelegate {
        func didChange(deviceOrientation: UIDeviceOrientation) {
            /// update UI in main thread
        }
    }
    

    APOrientationManager.swift

    import Foundation
    import CoreMotion
    import AVFoundation
    
    protocol APOrientationManagerDelegate: class {
        func didChange(deviceOrientation: UIDeviceOrientation)
    }
    
    class APOrientationManager {
    
        private let motionManager = CMMotionManager()
        private let queue = OperationQueue()
        private var deviceOrientation: UIDeviceOrientation = .unknown
        weak var delegate: APOrientationManagerDelegate?
    
        init() {
            motionManager.accelerometerUpdateInterval = 1.0
            motionManager.deviceMotionUpdateInterval = 1.0
            motionManager.gyroUpdateInterval = 1.0
            motionManager.magnetometerUpdateInterval = 1.0
        }
    
        func startMeasuring() {
            guard motionManager.isDeviceMotionAvailable else {
                return
            }
            motionManager.startAccelerometerUpdates(to: queue) { [weak self] (accelerometerData, error) in
                guard let strongSelf = self else {
                    return
                }
                guard let accelerometerData = accelerometerData else {
                    return
                }
    
                let acceleration = accelerometerData.acceleration
                let xx = -acceleration.x
                let yy = acceleration.y
                let z = acceleration.z
                let angle = atan2(yy, xx)
                var deviceOrientation = strongSelf.deviceOrientation
                let absoluteZ = fabs(z)
    
                if deviceOrientation == .faceUp || deviceOrientation == .faceDown {
                    if absoluteZ < 0.845 {
                        if angle < -2.6 {
                            deviceOrientation = .landscapeRight
                        } else if angle > -2.05 && angle < -1.1 {
                            deviceOrientation = .portrait
                        } else if angle > -0.48 && angle < 0.48 {
                            deviceOrientation = .landscapeLeft
                        } else if angle > 1.08 && angle < 2.08 {
                            deviceOrientation = .portraitUpsideDown
                        }
                    } else if z < 0 {
                        deviceOrientation = .faceUp
                    } else if z > 0 {
                        deviceOrientation = .faceDown
                    }
                } else {
                    if z > 0.875 {
                        deviceOrientation = .faceDown
                    } else if z < -0.875 {
                        deviceOrientation = .faceUp
                    } else {
                        switch deviceOrientation {
                        case .landscapeLeft:
                            if angle < -1.07 {
                                deviceOrientation = .portrait
                            }
                            if angle > 1.08 {
                                deviceOrientation = .portraitUpsideDown
                            }
                        case .landscapeRight:
                            if angle < 0 && angle > -2.05 {
                                deviceOrientation = .portrait
                            }
                            if angle > 0 && angle < 2.05 {
                                deviceOrientation = .portraitUpsideDown
                            }
                        case .portraitUpsideDown:
                            if angle > 2.66 {
                                deviceOrientation = .landscapeRight
                            }
                            if angle < 0.48 {
                                deviceOrientation = .landscapeLeft
                            }
                        case .portrait:
                            if angle > -0.47 {
                                deviceOrientation = .landscapeLeft
                            }
                            if angle < -2.64 {
                                deviceOrientation = .landscapeRight
                            }
                        default:
                            if angle > -0.47 {
                                deviceOrientation = .landscapeLeft
                            }
                            if angle < -2.64 {
                                deviceOrientation = .landscapeRight
                            }
                        }
                    }
                }
                if strongSelf.deviceOrientation != deviceOrientation {
                    strongSelf.deviceOrientation = deviceOrientation
                    strongSelf.delegate?.didChange(deviceOrientation: deviceOrientation)
                }
            }
        }
    
        func stopMeasuring() {
            motionManager.stopAccelerometerUpdates()
        }
    
        func currentInterfaceOrientation() -> AVCaptureVideoOrientation {
            switch deviceOrientation {
            case .portrait:
                return .portrait
            case .landscapeRight:
                return .landscapeLeft
            case .landscapeLeft:
                return .landscapeRight
            case .portraitUpsideDown:
                return .portraitUpsideDown
            default:
                return .portrait
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-12-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多