mirror of
https://github.com/yattee/yattee.git
synced 2024-12-15 06:40:32 +05:30
93 lines
3.1 KiB
Swift
93 lines
3.1 KiB
Swift
|
import CoreMotion
|
||
|
import UIKit
|
||
|
|
||
|
public class OrientationTracker {
|
||
|
public static let shared = OrientationTracker()
|
||
|
|
||
|
public static let deviceOrientationChangedNotification = NSNotification.Name("DeviceOrientationChangedNotification")
|
||
|
|
||
|
public var currentDeviceOrientation: UIDeviceOrientation = .portrait
|
||
|
|
||
|
public var currentInterfaceOrientation: UIInterfaceOrientation {
|
||
|
switch currentDeviceOrientation {
|
||
|
case .landscapeLeft:
|
||
|
return .landscapeLeft
|
||
|
case .landscapeRight:
|
||
|
return .landscapeRight
|
||
|
default:
|
||
|
return .portrait
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public var currentInterfaceOrientationMask: UIInterfaceOrientationMask {
|
||
|
switch currentInterfaceOrientation {
|
||
|
case .landscapeLeft:
|
||
|
return .landscapeLeft
|
||
|
case .landscapeRight:
|
||
|
return .landscapeRight
|
||
|
default:
|
||
|
return .portrait
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public var affineTransform: CGAffineTransform {
|
||
|
var angleRadians: Double
|
||
|
switch currentDeviceOrientation {
|
||
|
case .portrait:
|
||
|
angleRadians = 0
|
||
|
case .landscapeLeft:
|
||
|
angleRadians = -0.5 * .pi
|
||
|
case .landscapeRight:
|
||
|
angleRadians = 0.5 * .pi
|
||
|
case .portraitUpsideDown:
|
||
|
angleRadians = .pi
|
||
|
default:
|
||
|
return .identity
|
||
|
}
|
||
|
return CGAffineTransform(rotationAngle: angleRadians)
|
||
|
}
|
||
|
|
||
|
private let motionManager: CMMotionManager
|
||
|
private let queue: OperationQueue
|
||
|
|
||
|
private init() {
|
||
|
motionManager = CMMotionManager()
|
||
|
motionManager.accelerometerUpdateInterval = 0.1
|
||
|
queue = OperationQueue()
|
||
|
}
|
||
|
|
||
|
public func startDeviceOrientationTracking() {
|
||
|
motionManager.startAccelerometerUpdates(to: queue) { accelerometerData, error in
|
||
|
guard error == nil else { return }
|
||
|
guard let accelerometerData = accelerometerData else { return }
|
||
|
|
||
|
let newDeviceOrientation = self.deviceOrientation(forAccelerometerData: accelerometerData)
|
||
|
guard newDeviceOrientation != self.currentDeviceOrientation else { return }
|
||
|
self.currentDeviceOrientation = newDeviceOrientation
|
||
|
|
||
|
NotificationCenter.default.post(name: Self.deviceOrientationChangedNotification,
|
||
|
object: nil,
|
||
|
userInfo: nil)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public func stopDeviceOrientationTracking() {
|
||
|
motionManager.stopAccelerometerUpdates()
|
||
|
}
|
||
|
|
||
|
private func deviceOrientation(forAccelerometerData accelerometerData: CMAccelerometerData) -> UIDeviceOrientation {
|
||
|
let treshold = 0.55
|
||
|
if accelerometerData.acceleration.x >= treshold {
|
||
|
return .landscapeLeft
|
||
|
} else if accelerometerData.acceleration.x <= -treshold {
|
||
|
return .landscapeRight
|
||
|
} else if accelerometerData.acceleration.y <= -treshold {
|
||
|
return .portrait
|
||
|
} else if accelerometerData.acceleration.y >= treshold {
|
||
|
return .portraitUpsideDown
|
||
|
} else {
|
||
|
return currentDeviceOrientation
|
||
|
}
|
||
|
}
|
||
|
}
|