如何用requestGeometryUpdate实现APP方向随URL锁定,不受物理旋转影响?
解决Web页面切换时屏幕方向锁定问题
你的问题核心是:调用requestGeometryUpdate只是让系统切换到指定方向,但没有限制设备物理旋转的响应。要实现锁定方向直到新页面加载完成,需要通过动态控制视图控制器支持的方向集合来实现。
修改方案:
- 给
TestController添加属性存储当前允许的屏幕方向 - 重写
supportedInterfaceOrientations方法,返回这个属性的值 - 在URL变化的回调中,更新允许的方向并触发界面方向更新
修改后的完整代码:
import SwiftUI import WebKit struct TestView: View { private let urlString: String = "https://stackoverflow.com/" var body: some View { TestWebView(url: URL(string: urlString)!) .background(Color.black) .scrollIndicators(.hidden) .ignoresSafeArea([.all])//stretchs webview over notch on iphone .defersSystemGestures(on:.bottom)//deprioritizes multitasking indicator .statusBar(hidden: true)//hides time and battery } } class TestController: UIViewController { var webview: WKWebView! var webViewURLObserver: NSKeyValueObservation? // 新增:存储当前锁定的方向 private var lockedOrientation: UIInterfaceOrientationMask = .portrait override func viewDidLoad() { super.viewDidLoad() let winScene = UIApplication.shared.connectedScenes.first let windowScene = winScene as! UIWindowScene webview = WKWebView(frame: self.view.frame) webview.autoresizingMask = [.flexibleWidth,.flexibleHeight]//makes webview fit screen in portrait and landscape self.view.addSubview(self.webview) webViewURLObserver = self.webview.observe(\.url, options: .new) { [weak self] webview, change in guard let self = self, let url = change.newValue else { return } print(url) var portrait = false let urlStr = url.absoluteString // 精确匹配stackoverflow主页 portrait = urlStr == "https://stackoverflow.com/" // 更新锁定的方向 self.lockedOrientation = portrait ? .portrait : .landscape // 请求系统切换方向 windowScene.requestGeometryUpdate(.iOS(interfaceOrientations: self.lockedOrientation)) { error in if let error = error { print("方向更新失败:\(error.localizedDescription)") } } // 触发方向支持更新 self.setNeedsUpdateOfSupportedInterfaceOrientations() } // 初始加载时设置默认方向 self.lockedOrientation = .portrait self.setNeedsUpdateOfSupportedInterfaceOrientations() } // 重写:返回当前允许的方向 override var supportedInterfaceOrientations: UIInterfaceOrientationMask { return lockedOrientation } } // WebView Struct struct TestWebView: UIViewControllerRepresentable { let url: URL func makeUIViewController(context: Context) -> TestController { let webviewController = TestController() return webviewController } func updateUIViewController(_ webviewController: TestController, context: Context) { let request = URLRequest(url: url) webviewController.webview.scrollView.contentInsetAdjustmentBehavior = .never webviewController.webview.load(request) } } struct TestView_Previews: PreviewProvider { static var previews: some View { TestView() } }
关键说明:
lockedOrientation属性动态控制当前允许的方向,设置为.portrait或.landscape后,设备物理旋转时不会触发方向变化- 重写
supportedInterfaceOrientations是核心,系统会根据这个值限制允许的屏幕方向 - 在URL变化回调中,先更新
lockedOrientation,再调用requestGeometryUpdate切换方向,最后触发setNeedsUpdateOfSupportedInterfaceOrientations让系统应用新的方向限制 - 初始加载时设置默认方向,确保启动时就锁定正确姿态
内容的提问来源于stack exchange,提问作者user1763510
相关产品推荐
相关产品推荐

