5

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

enter image description 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!

NNN
  • 543
  • 5
  • 14

0 Answers0