How to Forcefully Implement Orientation for a Particular View in SwiftUI?
Sometimes, we may need to restrict the orientation of our SwiftUI view to a specific mode, for example, to ensure that our video player is always in landscape mode or a reading app is always in portrait mode. In this article, I will explain how can we implement orientation forcefully on a particular view.
class AppDelegate: NSObject, UIApplicationDelegate {
static var orientationLock = UIInterfaceOrientationMask.portrait {
didSet {
if #available(iOS 16.0, *) {
UIApplication.shared.connectedScenes.forEach { scene in
if let windowScene = scene as? UIWindowScene {
windowScene.requestGeometryUpdate(.iOS(interfaceOrientations: orientationLock))
}
}
UIViewController.attemptRotationToDeviceOrientation()
} else {
let orientation: UIInterfaceOrientation = orientationLock == .portrait ? .portrait : .landscapeRight
UIDevice.current.setValue(orientation.rawValue, forKey: "orientation")
}
}
}
func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
return AppDelegate.orientationLock
}
}
extension View {
@ViewBuilder
func force(orientation: UIInterfaceOrientationMask) -> some View {
self.onAppear() {
AppDelegate.orientationLock = orientation
}
let currentOrientation = AppDelegate.orientationLock
self.onDisappear() {
AppDelegate.orientationLock = currentOrientation
}
}
}
AppDelegate
: it’sUIApplicationDelegate
. It includes a static variable calledorientationLock
, which holds the current interface orientation. This variable is used to restrict the supported interface orientations of the app. If the device is running on iOS 16.0 or later, it requests a geometry update to update the supported orientations asUIDevice.current
is no longer supported in iOS 16 onwards. Then it attempts to rotate to the current device orientation. If the device is running on a version of iOS prior to 16.0, it uses the deprecatedUIDevice.current.setValue
method to set the interface orientation.View.force(orientation:)
: This is an extension onView
that adds a modifier to force a particular orientation on the view. The modifier takes anorientation
parameter, which is aUIInterfaceOrientationMask
that represents the supported orientations.
We need to use the AppDelegate
class as shown below:
@main
struct DesigningDependenciesApp: App {
@UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
var body: some Scene {
WindowGroup {
PortraitView()
}
}
}
How to Use It?
struct PortraitView: View {
var body: some View {
Text("This view is in portrait mode!")
.force(orientation: .portrait)
}
}
struct LandscapeView: View {
var body: some View {
Text("This view is in landscape mode!")
.force(orientation: .landscape)
}
}
Conclusion — In this article, we learned how to forcefully implement orientation for a particular view in SwiftUI. We showed how to use the force(orientation:)
modifier to restrict the orientation of a view, and how to implement the required code to achieve this functionality. I hope this article helps you in your SwiftUI development efforts.