如何在WKWebView点击链接时弹出Sheet展示链接内容?
解决方案
要实现WKWebView内点击链接弹出独立Sheet展示页面,核心是通过绑定状态在SwiftUI视图层级和UIKit的Coordinator之间传递交互信号,具体修改如下:
1. 定义Sheet用的WebView组件
先封装一个专门用于Sheet的WKWebView包装,方便复用:
struct WebViewSheet: UIViewRepresentable { let url: URL func makeUIView(context: Context) -> WKWebView { let webView = WKWebView() webView.load(URLRequest(url: url)) return webView } func updateUIView(_ uiView: WKWebView, context: Context) {} }
2. 修改HTMLView,添加绑定状态
给HTMLView添加两个绑定变量,用于控制Sheet的显示和要加载的URL,同时启用NavigationDelegate:
struct HTMLView: UIViewRepresentable { let html: String // 添加绑定状态,用于通知SwiftUI弹出Sheet @Binding var showSheet: Bool @Binding var sheetURL: URL? func makeUIView(context: Context) -> WKWebView { let webView = WKWebView() webView.navigationDelegate = context.coordinator // 启用导航代理 return webView } func updateUIView(_ uiView: WKWebView, context: Context) { uiView.loadHTMLString(html, baseURL: nil) } func makeCoordinator() -> Coordinator { Coordinator(self) } class Coordinator: NSObject, WKNavigationDelegate { let parent: HTMLView init(_ parent: HTMLView) { self.parent = parent } func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) { guard let url = navigationAction.request.url, url.scheme != "about" else { decisionHandler(.allow) return } // 拦截有效链接,触发Sheet弹出 parent.sheetURL = url parent.showSheet = true decisionHandler(.cancel) // 取消默认跳转行为 } } }
3. 修改DetailsView,添加Sheet逻辑
在DetailsView中添加状态变量,管理Sheet的显示,并将状态绑定到HTMLView:
struct DetailsView: View { let item: MyItem // 本地状态控制Sheet显示 @State private var showSheet = false @State private var sheetURL: URL? var body: some View { HTMLView(html: item.html, showSheet: $showSheet, sheetURL: $sheetURL) .padding(30) .sheet(isPresented: $showSheet) { // Sheet中展示目标页面 if let url = sheetURL { WebViewSheet(url: url) .edgesIgnoringSafeArea(.all) } } } }
关键说明
- 通过
@Binding实现UIKit层(Coordinator)和SwiftUI视图层的状态同步,Coordinator拦截到链接后,更新绑定状态触发Sheet弹出 - 拦截链接时过滤掉
about:blank这类无效URL,只处理真实的外部链接 - 调用
decisionHandler(.cancel)阻止WKWebView默认的跳转行为,确保链接只通过Sheet展示
内容的提问来源于stack exchange,提问作者dudette
相关产品推荐
相关产品推荐

