mirror of
https://github.com/yattee/yattee.git
synced 2025-10-12 10:28:11 +00:00
Orientation improvements
This commit is contained in:
92
iOS/OrientationTracker.swift
Normal file
92
iOS/OrientationTracker.swift
Normal file
@@ -0,0 +1,92 @@
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user