
This can be achieved using a View extension
that will update the view's orientation. Let’s make our own extension which will rotate
the view
on given orientation, back and forth.
extension View {
@ViewBuilder
func forceRotation(orientation: UIInterfaceOrientationMask) -> some View {
if UIDevice.current.userInterfaceIdiom == .phone {
self.onAppear() {
AppDelegate.orientationLock = orientation
}
// Reset orientation to previous setting
let currentOrientation = AppDelegate.orientationLock
self.onDisappear() {
AppDelegate.orientationLock = currentOrientation
}
} else {
self
}
}
}
In AppDelegate, add:
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 {
if orientationLock == .landscape {
UIDevice.current.setValue(UIInterfaceOrientation.landscapeRight.rawValue, forKey: "orientation")
} else {
UIDevice.current.setValue(UIInterfaceOrientation.portrait.rawValue, forKey: "orientation")
}
}
}
}
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
return true
}
func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
return AppDelegate.orientationLock
}
}
This little example demonstrate how you can use this extension:
struct ContentView: View {
var body: some View {
NavigationView {
List(Orientation.allCases, id: \.self) { orientation in
NavigationLink(orientation.title) {
ZStack {
Text(orientation.title)
}
.forceRotation(orientation: orientation.mask) // << Update the required orientation here..
}
}
}
}
}
enum Orientation: Int CaseIterable {
case landscapeLeft
case landscapeRight
var title: String {
switch self {
case .landscapeLeft:
return "LandscapeLeft"
case .landscapeRight:
return "LandscapeRight"
}
}
var mask: UIInterfaceOrientationMask {
switch self {
case .landscapeLeft:
return .landscapeLeft
case .landscapeRight:
return .landscapeRight
}
}
}