我想获取当前iOS设备方向,即使设备的方向已锁定。(就像iOS相机应用程序一样)我想至少检测纵向、左横向和右横向。锁定方向时,UIDeviceOrientation和UIInterfaceOrientation似乎不起作用。在这种情况下,我认为我们将使用CoreMotion。在swift4中如何进行逻辑运算?
8fsztsew1#
使用Core Motion声明运动管理器
var orientationLast = UIInterfaceOrientation(rawValue: 0)! var motionManager: CMMotionManager?
运动管理器初始化
并在viewDidLoad中调用此函数
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 }
vhipe2zx2#
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 }
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 } } }
3条答案
按热度按时间8fsztsew1#
使用Core Motion声明运动管理器
运动管理器初始化
并在
viewDidLoad
中调用此函数分析加速计数据
vhipe2zx2#
cqoc49vn3#
下面是一个检测设备旋转并返回UIDeviceOrientation的示例。该解决方案使用CoreMotion,适用于所有情况。
一致委托
APOrientationManager.swift