Orientation improvements

This commit is contained in:
Arkadiusz Fal
2022-07-10 00:29:13 +02:00
parent 6c71cd72b1
commit 5f858bc6d4
8 changed files with 144 additions and 138 deletions

View File

@@ -19,6 +19,8 @@ final class AppDelegate: UIResponder, UIApplicationDelegate {
UITabBar.appearance().backgroundImage = UIImage()
UITabBar.appearance().isTranslucent = true
UITabBar.appearance().backgroundColor = .clear
OrientationTracker.shared.startDeviceOrientationTracking()
#endif
return true
}

View File

@@ -21,11 +21,16 @@ struct Orientation {
static func lockOrientation(_ orientation: UIInterfaceOrientationMask, andRotateTo rotateOrientation: UIInterfaceOrientation? = nil) {
lockOrientation(orientation)
guard !rotateOrientation.isNil else {
guard let rotateOrientation = rotateOrientation else {
return
}
UIDevice.current.setValue(rotateOrientation!.rawValue, forKey: "orientation")
let orientationString = rotateOrientation == .portrait ? "portrait" : rotateOrientation == .landscapeLeft ? "landscapeLeft" :
rotateOrientation == .landscapeRight ? "landscapeRight" : rotateOrientation == .portraitUpsideDown ? "portraitUpsideDown" : "allButUpsideDown"
logger.info("rotating to \(orientationString)")
UIDevice.current.setValue(rotateOrientation.rawValue, forKey: "orientation")
UINavigationController.attemptRotationToDeviceOrientation()
}
}

View 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
}
}
}