多WKWebView实例下独立didFinish代理方法及差异化加载操作实现
当然可以实现不同WKWebView实例在加载完成时执行各自的操作!这里有两种常用的方案,你可以根据自己的业务场景灵活选择:
方案1:在同一个代理类中区分WebView实例
这种方法适合两个WebView的加载完成逻辑比较简单的场景,只需要在didFinish代理方法里判断当前回调的是哪个WebView实例即可。
实现步骤:
- 让你的ViewController(或其他类)遵循
WKNavigationDelegate协议; - 初始化两个WKWebView实例,并将它们的
navigationDelegate都设置为当前类; - 在
didFinish方法中用===判断当前webView的引用是否和目标实例一致,然后执行对应操作。
代码示例:
class ViewController: UIViewController, WKNavigationDelegate { // 定义两个WebView实例 var webView1: WKWebView! var webView2: WKWebView! override func viewDidLoad() { super.viewDidLoad() // 初始化webView1并设置代理 let config1 = WKWebViewConfiguration() webView1 = WKWebView(frame: CGRect(x: 0, y: 100, width: view.frame.width, height: 200), configuration: config1) webView1.navigationDelegate = self view.addSubview(webView1) // 初始化webView2并设置代理 let config2 = WKWebViewConfiguration() webView2 = WKWebView(frame: CGRect(x: 0, y: 350, width: view.frame.width, height: 200), configuration: config2) webView2.navigationDelegate = self view.addSubview(webView2) // 加载各自的URL webView1.load(URLRequest(url: URL(string: "https://example1.com")!)) webView2.load(URLRequest(url: URL(string: "https://example2.com")!)) } // 实现didFinish方法,区分不同WebView func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) { // 用===判断引用是否相同,确保是同一个实例 if webView === webView1 { print("webView1加载完成!") // 这里写webView1的专属操作,比如修改标题、弹出提示等 webView1.title = "WebView1 加载完成" } else if webView === webView2 { print("webView2加载完成!") // 这里写webView2的专属操作,比如执行JS、刷新UI等 webView2.evaluateJavaScript("document.body.style.color = '#333'") { _, error in if let error = error { print("执行JS失败:\(error.localizedDescription)") } } } } }
方案2:为每个WebView创建独立的代理类
如果两个WebView的加载完成逻辑比较复杂,或者你想让代码职责更清晰,推荐给每个WebView单独创建一个代理类,这样每个代理的didFinish方法就是完全独立的。
实现步骤:
- 分别创建两个遵循
WKNavigationDelegate的代理类,各自实现didFinish方法; - 在ViewController中初始化这两个代理对象(注意要持有,避免被释放);
- 给每个WebView设置对应的代理对象。
代码示例:
// webView1的专属代理类 class WebView1Delegate: NSObject, WKNavigationDelegate { func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) { print("webView1加载完成,执行专属逻辑") // 这里可以写webView1的所有加载完成操作,逻辑独立 webView.reload() // 示例:重新加载一次(仅作演示) } } // webView2的专属代理类 class WebView2Delegate: NSObject, WKNavigationDelegate { func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) { print("webView2加载完成,执行专属逻辑") // 这里可以写webView2的所有加载完成操作 webView.scrollView.isScrollEnabled = false // 示例:禁止滚动 } } // 在ViewController中使用 class ViewController: UIViewController { var webView1: WKWebView! var webView2: WKWebView! // 持有代理对象,避免被ARC释放 let webView1Delegate = WebView1Delegate() let webView2Delegate = WebView2Delegate() override func viewDidLoad() { super.viewDidLoad() let config1 = WKWebViewConfiguration() webView1 = WKWebView(frame: CGRect(x: 0, y: 100, width: view.frame.width, height: 200), configuration: config1) webView1.navigationDelegate = webView1Delegate view.addSubview(webView1) let config2 = WKWebViewConfiguration() webView2 = WKWebView(frame: CGRect(x: 0, y: 350, width: view.frame.width, height: 200), configuration: config2) webView2.navigationDelegate = webView2Delegate view.addSubview(webView2) webView1.load(URLRequest(url: URL(string: "https://example1.com")!)) webView2.load(URLRequest(url: URL(string: "https://example2.com")!)) } }
注意事项:
- WKWebView对代理的引用是弱引用,所以一定要确保代理对象被持有(比如作为ViewController的属性),否则代理方法不会被调用;
- 用
===判断实例时,要确保是同一个对象的引用,而不是值相等,这在区分同一类型的不同实例时非常关键。
内容的提问来源于stack exchange,提问作者Ben
相关产品推荐
相关产品推荐

