You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift中如何从WebView跳转链接至Safari?

解决SwiftUI中UIViewRepresentable实现的WebView跳转链接到Safari的问题

你的WebView无法打开内部链接,是因为没有设置导航代理拦截跳转请求。要实现点击链接跳转到Safari,需要通过WKNavigationDelegate拦截请求,然后调用系统方法打开外部浏览器。

以下是修改后的完整代码:

import Foundation
import SwiftUI
import WebKit

struct WebView: UIViewRepresentable {
    let url: URL
    
    // 定义Coordinator,处理WKWebView的代理回调
    class Coordinator: NSObject, WKNavigationDelegate {
        func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
            guard let url = navigationAction.request.url else {
                decisionHandler(.allow)
                return
            }
            
            // 判断是否为可外部打开的链接
            if UIApplication.shared.canOpenURL(url) {
                // 跳转至Safari打开链接
                UIApplication.shared.open(url)
                // 取消WebView内部加载
                decisionHandler(.cancel)
            } else {
                // 无法外部打开的链接,允许WebView内部加载
                decisionHandler(.allow)
            }
        }
    }
    
    func makeCoordinator() -> Coordinator {
        Coordinator()
    }
    
    func makeUIView(context: Context) -> some UIView {
        let webView = WKWebView()
        // 设置导航代理为Coordinator
        webView.navigationDelegate = context.coordinator
        let request = URLRequest(url: url)
        webView.load(request)
        return webView
    }
    
    func updateUIView(_ uiView: UIViewType, context: Context) {
        
    }
}

关键说明:

  • Coordinator:作为WKNavigationDelegate的实现载体,负责接收WebView的导航事件回调。
  • decidePolicyFor方法:核心拦截逻辑,判断链接是否可被系统外部打开,若满足条件则启动Safari并终止WebView的内部加载;否则让WebView自行处理请求。
  • 权限配置:如果链接使用自定义协议(非http/https这类默认支持的Scheme),需要在Info.plist中添加LSApplicationQueriesSchemes数组,将对应协议加入其中。

内容的提问来源于stack exchange,提问作者user8359454

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 17:52:40