I am working on an app which uses viewcontrollers and I am slowly migrating to use views built using SwiftUI.
I am working on new swiftUI views, so i am setting UIHostingController as the rootViewController in the SceneDelegate
Overall my whole app is restricted to portrait only here
There are some individual views that i want to allow to be shown in portrait and landscape left
This is what i have used so far for swiftUI, that works perfectly in iOS 15
in AppDelegate i have
static var orientationLock = UIInterfaceOrientationMask.portrait
then in the method
func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask
this is set to return
return AppDelegate.orientationLock
Then in the particular swiftUI file i want to allow rotation, i simply have to do this to handle screen rotations by adding this modifier to the main view
.onReceive(NotificationCenter.default.publisher(for: UIDevice.orientationDidChangeNotification)) { _ in
if orientation.isLandscape {
AppDelegate.orientationLock = UIInterfaceOrientationMask.landscapeLeft
UIDevice.current.setValue(UIInterfaceOrientation.landscapeLeft.rawValue, forKey: "orientation")
UINavigationController.attemptRotationToDeviceOrientation()
} else {
AppDelegate.orientationLock = UIInterfaceOrientationMask.portrait
UIDevice.current.setValue(UIInterfaceOrientation.portrait.rawValue, forKey: "orientation")
UINavigationController.attemptRotationToDeviceOrientation()
}
}
.onDisappear {
DispatchQueue.main.async {
AppDelegate.orientationLock = UIInterfaceOrientationMask.portrait
UIDevice.current.setValue(UIInterfaceOrientation.portrait.rawValue, forKey: "orientation")
UINavigationController.attemptRotationToDeviceOrientation()
}
}
However iOS 16 has depreciated the code:
UIDevice.current.setValue(UIInterfaceOrientation.landscapeLeft.rawValue, forKey: "orientation")
we get an error message, BUG IN CLIENT OF UIKIT: Setting UIDevice.orientation is not supported. Please use UIWindowScene.requestGeometryUpdate(_:)
we are now told in Apples documentation to simply call the code below from a UIViewcontroller:
let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene
windowScene?.requestGeometryUpdate(.iOS(interfaceOrientations: .landscapeLeft))
however this code simply does not work for me, i want to be able to call the code from the swiftUI file, and when i try calling the code from the swiftUI file, nothing happens. How can i make this work? To be clear, i need to be able to call a method/modifier from within the swiftUI file, that will allow the screen to rotate just for that screen (i.e. when I navigate to another screen, it will be back to portrait)
I think i have to try to access UIHostingController somehow from the swiftUI file and call requestGeometryUpdate via that, I have tried different ways of doing this, but clearly what i've tried so far does not work!