iOS中如何检查应用方向(而非设备物理方向)
Hey there! I totally get your frustration with UIDevice.current.orientation—it’s strictly tied to the device’s physical position in 3D space, which means it fails when the device is laid flat (like on a desk) even if your app’s interface is still in portrait mode. Let’s go over the right approaches to check your app’s actual layout direction, depending on your target iOS version:
iOS 13+ (Recommended for Modern Apps)
Apple deprecated the old statusBarOrientation API in iOS 13, so we now rely on UIWindowScene to get the app’s interface orientation. This value reflects how your app’s UI is actually laid out, not just the device’s physical tilt:
// Fetch the active window scene if let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene { let appOrientation = windowScene.interfaceOrientation if appOrientation.isPortrait { // App is displaying in portrait layout } else { // App is displaying in landscape layout } }
This works perfectly even when the device is face-up or face-down—because it’s tracking the app’s interface state, not the device’s physical orientation.
Alternative: Use Trait Collections (Great for View Controllers)
If you’re working inside a view controller, using trait collections is even more intuitive, since it’s directly tied to the layout context of your UI. Plus, the system automatically calls traitCollectionDidChange when the orientation changes, so you can react to updates seamlessly:
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) { super.traitCollectionDidChange(previousTraitCollection) // Check size classes to determine orientation if traitCollection.verticalSizeClass == .regular && traitCollection.horizontalSizeClass == .compact { // Portrait layout (standard for iPhones in portrait, iPads in split view portrait) } else { // Landscape layout (or iPad split view landscape) } }
This approach is especially useful if you need to adjust your UI layout dynamically as the orientation changes.
Why Your Original Code Fails
Just to clarify: UIDevice.current.orientation returns values like .faceUp or .faceDown when the device is laid flat. Since UIDeviceOrientationIsPortrait only returns true for .portrait or .portraitUpsideDown, your code would fall into the else branch even though the app’s interface is still portrait—hence the issue you’re seeing.
内容的提问来源于stack exchange,提问作者Fab

