SwiftUI中WKWebView无法弹出Alert的问题排查求助
问题原因
控制台核心错误提示:Attempt to present <SwiftUI.PlatformAlertController> ... which is already presenting <_TtGC7SwiftUI29PresentationHostingController>,说明你试图在已经弹出fullScreenCover模态视图的父视图上展示Alert,而iOS不允许一个视图控制器同时present两个模态视图,导致Alert无法显示。
解决方案
将Alert的状态和展示逻辑从父视图(ContentView)移到fullScreenCover内部的视图层级中,让Alert属于当前显示的模态视图,而非父视图。同时确保UI操作在主线程执行。
步骤1:创建WebView容器视图
新增WebViewContainer视图,封装WebView和对应的Alert逻辑:
struct WebViewContainer: View { let urlString: String @State private var showError = false @State private var errorMessage = "" var body: some View { if let url = URL(string: urlString) { WebView(url: url) { error in // 确保在主线程更新UI状态 DispatchQueue.main.async { errorMessage = error showError = true } } } else { Text("not valid url") } // 将Alert附加到当前模态视图 .alert(isPresented: $showError) { Alert(title: Text("Error"), message: Text(errorMessage), dismissButton: .default(Text("OK"))) } } }
步骤2:修改ContentView的fullScreenCover调用
替换原来的fullScreenCover内容,使用新的容器视图:
struct ContentView: View { @State private var showWebView = false var body: some View { Button("open WebView") { showWebView = true } .fullScreenCover(isPresented: $showWebView) { WebViewContainer(urlString: "https://www.google.com") } } }
步骤3:确保WKNavigationDelegate方法在主线程触发回调
修改WebView Coordinator中的回调逻辑,强制在主线程执行(避免UI操作在后台线程引发的问题):
class Coordinator: NSObject, WKNavigationDelegate { var parent: WebView init(_ parent: WebView) { self.parent = parent } func webView(_ webView: WKWebView, didFailProvisionalNavigation navigation: WKNavigation!, withError error: Error) { DispatchQueue.main.async { self.parent.handleError?(error.localizedDescription) } } func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) { DispatchQueue.main.async { self.parent.handleError?("Hello, fake error for testing") } } }
额外说明
- 控制台中的
[Security] This method should not be called on the main thread提示,是WKWebView内部的Cookie相关操作(你提到的监控Cookie任务)在主线程执行导致的,后续处理Cookie逻辑时,建议将耗时操作放到后台线程执行,避免UI卡顿。 - iOS 15的SwiftUI模态视图层级管理严格,所有模态相关的UI操作(如Alert、Sheet)必须附加到当前活跃的模态视图上,不能跨层级触发。
内容的提问来源于stack exchange,提问作者biggreentree
相关产品推荐
相关产品推荐

