Deepak Sharma
Deepak Sharma

Reputation: 6581

Fix orientation of just ONE view in SwiftUI to portrait

I have seen lots and lots of answers to this but haven't found a satisfactory one so far. I am targeting iOS 17+ and want one of the subviews (for a custom camera preview) to be locked to portrait orientation while allowing all others to freely rotate. The custom view for camera preview is UIViewRepresentable which I want to be locked to portrait orientation. For the record, I have seen the following approaches:

  1. Implementing an AppDelegate,

     class AppDelegate: NSObject, UIApplicationDelegate {
    
     static var orientationLock = UIInterfaceOrientationMask.portrait //By default you want all your views to rotate freely
    
     func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
         return AppDelegate.orientationLock
     }
    

    }

But it sets the whole app to portrait orientation than just the view.

  1. UIDevice based set orientation methods: no longer work and its not clear how they can be used to lock orientation of just one view.

  2. Trying updation through UIScene but even this doesn't work as expected. The view first rotates and then unrotates, and in the process rotates the whole view hierarchy rather than just the view in question.

    SampleBufferView(viewModel: camera, sampleBuffer: latestSample)
                    .aspectRatio(verticalSizeClass == .regular ? 9.0/16.0 : 16.0/9.0, contentMode: .fit)
                    .onAppear {
                        if let scene = UIApplication.shared.connectedScenes.first as? UIWindowScene {
                            scene.requestGeometryUpdate(.iOS(interfaceOrientations: .portrait)) { error in
                                // Handle denial of request.
                            }
                        }
                    }
                    .onGeometryChange(for: CGSize.self, of: { proxy in
                        proxy.size
                    }, action: { newValue in
                        requestOrientations(.portrait)
                    })
    
    
    
    private func requestOrientations(_ orientations: UIInterfaceOrientationMask) {
    if let scene = UIApplication.shared.connectedScenes.first as? UIWindowScene {
        scene.requestGeometryUpdate(.iOS(interfaceOrientations: orientations)) { error in
            // Handle denial of request.
        }
    }
    

    }

Upvotes: 0

Views: 64

Answers (0)

Related Questions