swift 获取当前iOS设备方向,即使设备的方向已锁定

vxqlmq5t  于 2023-02-07  发布在  Swift
关注(0)|答案(3)|浏览(203)

我想获取当前iOS设备方向,即使设备的方向已锁定。(就像iOS相机应用程序一样)
我想至少检测纵向、左横向和右横向。
锁定方向时,UIDeviceOrientation和UIInterfaceOrientation似乎不起作用。
在这种情况下,我认为我们将使用CoreMotion。
在swift4中如何进行逻辑运算?

8fsztsew

8fsztsew1#

使用Core Motion声明运动管理器

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.outputAccelerationData((accelerometerData?.acceleration)!)
        }
        else {
            print("\(error!)")
        }
        })
     }

分析加速计数据

func outputAccelerationData(_ 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
}
vhipe2zx

vhipe2zx2#

    • 雨燕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

 }
cqoc49vn

cqoc49vn3#

下面是一个检测设备旋转并返回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
        }
    }
}

相关问题