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:
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.
UIDevice based set orientation methods: no longer work and its not clear how they can be used to lock orientation of just one view.
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. } }
}