WKWebView didFinish Navigation仅触发一次且页面导航后按钮未消失求助
看起来你已经搞定了匹配URL时显示按钮的逻辑,但漏掉了页面导航离开时的按钮隐藏处理——这是WKWebView开发里很容易忽略的细节,我给你几个具体的排查和解决方向:
检查你监听的回调事件是否完整
你大概率只在webView(_:didFinish:)回调里处理了按钮显示,但这个方法只有页面加载完成时才会触发。当用户导航到新页面(前进、后退、跳转链接)时,这个方法不会主动帮你隐藏旧页面的按钮。解决办法是:在页面开始加载新内容时先默认隐藏按钮,再在加载完成后根据URL决定是否显示。比如同时实现这两个回调:
func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) { // 新页面开始加载时,先把按钮藏起来 customButton.isHidden = true } func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) { guard let currentURL = webView.url else { return } // 匹配你的目标URL规则 let shouldShowButton = currentURL.absoluteString.contains("your-target-url-pattern") customButton.isHidden = !shouldShowButton }另外别忘了处理页面加载失败的情况,在
webView(_:didFail:withError:)里也把按钮隐藏掉,避免异常状态下残留。监听WKWebView的URL属性变化
有些场景下(比如JS触发的页面跳转、内部重定向),可能不会触发所有导航回调,这时候直接监听url属性的变化会更可靠。可以用KVO或者Combine:
用KVO的示例代码:// 在初始化WKWebView后添加监听 webView.addObserver(self, forKeyPath: "url", options: .new, context: nil) // 实现监听方法 override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) { guard keyPath == "url", let currentURL = webView.url else { return } customButton.isHidden = !currentURL.absoluteString.contains("your-target-url-pattern") } // 记得在deinit里移除监听,避免内存泄漏 deinit { webView.removeObserver(self, forKeyPath: "url") }检查按钮的视图层级
如果你把按钮添加到了WKWebView的父视图(比如ViewController的view),而不是和WebView关联的容器里,那么WebView的导航行为不会自动影响按钮的显示状态。这时候要确保按钮的显示/隐藏逻辑完全和WebView的当前URL绑定,而不是只在第一次加载时设置一次。测试重定向等边界场景
如果目标页面存在重定向,你可能需要在webView(_:didReceiveServerRedirectForProvisionalNavigation:)里提前判断最终的URL,避免重定向后按钮状态出错。
内容的提问来源于stack exchange,提问作者PocketTim

