How to Forcefully Implement Orientation for a Particular View in SwiftUI?

Virender Verma
2 min readMay 3, 2023

--

Portrait / Landscape

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
}
}
}
  1. AppDelegate: it’s UIApplicationDelegate. It includes a static variable called orientationLock, 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 as UIDevice.currentis 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 deprecated UIDevice.current.setValue method to set the interface orientation.
  2. View.force(orientation:): This is an extension on View that adds a modifier to force a particular orientation on the view. The modifier takes an orientation parameter, which is a UIInterfaceOrientationMask 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.

--

--

Virender Verma
Virender Verma

No responses yet