Last active
November 27, 2024 10:51
-
-
Save HarryGoodwin/414902bda35f66eeb3a1d424273ec057 to your computer and use it in GitHub Desktop.
Detecting Device Rotation In Swift
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import UIKit | |
import SwiftUI | |
@MainActor | |
@Observable | |
public final class OrientationMonitor { | |
public enum RotationDirection: String { | |
case anticlockwise | |
case clockwise | |
case unknown | |
} | |
public private(set) var current: UIDeviceOrientation | |
public private(set) var lastRotation: RotationDirection | |
public init() { | |
current = UIDevice.current.orientation | |
lastRotation = .unknown | |
Task { | |
for await notification in NotificationCenter.default.notifications(named: UIDevice.orientationDidChangeNotification) { | |
guard let device = notification.object as? UIDevice else { return } | |
let newOrientation = device.orientation | |
let direction = calculateRotationDirection( | |
newOrientation: newOrientation, | |
currentOrientation: current | |
) | |
current = newOrientation | |
lastRotation = direction | |
} | |
} | |
} | |
private func calculateRotationDirection( | |
newOrientation: UIDeviceOrientation, | |
currentOrientation: UIDeviceOrientation | |
) -> RotationDirection { | |
var direction: RotationDirection = .unknown | |
switch newOrientation { | |
case .unknown: | |
return .unknown | |
case .portrait: | |
switch currentOrientation { | |
case .portrait: | |
direction = .unknown | |
case .portraitUpsideDown: | |
direction = .unknown | |
case .landscapeLeft: | |
direction = .clockwise | |
case .landscapeRight: | |
direction = .anticlockwise | |
case .unknown, .faceUp, .faceDown: | |
direction = .unknown | |
@unknown default: | |
direction = .unknown | |
} | |
case .portraitUpsideDown: | |
switch currentOrientation { | |
case .portrait: | |
direction = .unknown | |
case .portraitUpsideDown: | |
direction = .unknown | |
case .landscapeLeft: | |
direction = .anticlockwise | |
case .landscapeRight: | |
direction = .clockwise | |
case .unknown, .faceUp, .faceDown: | |
direction = .unknown | |
@unknown default: | |
direction = .unknown | |
} | |
case .landscapeLeft: | |
switch currentOrientation { | |
case .portrait: | |
direction = .anticlockwise | |
case .portraitUpsideDown: | |
direction = .clockwise | |
case .landscapeLeft: | |
direction = .unknown | |
case .landscapeRight: | |
direction = .unknown | |
case .unknown, .faceUp, .faceDown: | |
direction = .unknown | |
@unknown default: | |
direction = .unknown | |
} | |
case .landscapeRight: | |
switch currentOrientation { | |
case .portrait: | |
direction = .clockwise | |
case .portraitUpsideDown: | |
direction = .anticlockwise | |
case .landscapeLeft: | |
direction = .unknown | |
case .landscapeRight: | |
direction = .unknown | |
case .unknown, .faceUp, .faceDown: | |
direction = .unknown | |
@unknown default: | |
direction = .unknown | |
} | |
case .faceDown, .faceUp: | |
break | |
@unknown default: | |
break | |
} | |
return direction | |
} | |
} | |
/// This is not needed for operation, just for a text representation of the | |
/// orientation in the demo. | |
extension UIDeviceOrientation { | |
var displayValue: String { | |
switch self { | |
case .unknown: | |
"unknown" | |
case .portrait: | |
"portrait" | |
case .portraitUpsideDown: | |
"portraitUpsideDown" | |
case .landscapeLeft: | |
"landscapeLeft" | |
case .landscapeRight: | |
"landscapeRight" | |
case .faceUp: | |
"faceUp" | |
case .faceDown: | |
"faceDown" | |
@unknown default: | |
"unknown" | |
} | |
} | |
} | |
/// Test View | |
struct OrientationView: View { | |
@State var orientation = OrientationMonitor() | |
var body: some View { | |
VStack { | |
Text(orientation.current.displayValue) | |
Text(orientation.lastRotation.rawValue) | |
} | |
.padding() | |
} | |
} | |
#Preview { | |
OrientationView() | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment