Swift中如何检测WKWebView是否包含指定文本以添加分享按钮?
检测WKWebView中的特定文本(Swift实现)
当然可以!在Swift里我们有几种靠谱的方案来实现这个需求——检测WKWebView加载的网页里是否包含指定文本(比如你提到的“Age”),然后根据结果显示标签栏的分享按钮。下面我给你详细拆解两种常用方法,适配不同的场景:
方法1:页面加载完成后注入JavaScript检测
这是最直接高效的方式,利用WKWebView的JS执行能力,让网页自身查找目标文本,适合静态页面或者加载完成后内容不再变化的场景。
实现步骤&代码示例
import WebKit class WebViewController: UIViewController, WKNavigationDelegate { private var webView: WKWebView! private var shareButton: UIBarButtonItem! override func viewDidLoad() { super.viewDidLoad() // 初始化WKWebView let webConfig = WKWebViewConfiguration() webView = WKWebView(frame: view.bounds, configuration: webConfig) webView.navigationDelegate = self view.addSubview(webView) // 初始化分享按钮(默认隐藏/禁用) shareButton = UIBarButtonItem(barButtonSystemItem: .action, target: self, action: #selector(shareButtonTapped)) shareButton.isEnabled = false shareButton.tintColor = .clear navigationItem.rightBarButtonItem = shareButton // 加载目标网页 if let targetURL = URL(string: "你的目标网页URL") { webView.load(URLRequest(url: targetURL)) } } // 网页加载完成后执行文本检测 func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) { // 编写JS脚本:检测页面是否包含"Age",这里用不区分大小写的匹配 let detectionJS = """ document.body.innerText.toLowerCase().includes('age') """ webView.evaluateJavaScript(detectionJS) { [weak self] result, error in guard let self = self else { return } guard let containsTargetText = result as? Bool else { return } // 根据检测结果更新分享按钮状态 if containsTargetText { self.shareButton.isEnabled = true self.shareButton.tintColor = nil // 恢复默认颜色 } else { self.shareButton.isEnabled = false self.shareButton.tintColor = .clear } } } @objc private func shareButtonTapped() { // 实现分享逻辑 guard let currentURL = webView.url else { return } let activityVC = UIActivityViewController(activityItems: [currentURL], applicationActivities: nil) present(activityVC, animated: true) } }
小调整说明
- 如果需要严格区分大小写,去掉JS里的
.toLowerCase()即可; - 如果要匹配完整单词(避免匹配到包含"Age"的其他单词,比如"Ageing"),可以用正则表达式:
/\bAge\b/.test(document.body.innerText),其中\b代表单词边界。
方法2:监听动态内容变化(适配异步加载场景)
如果你的网页是动态加载内容的(比如AJAX异步加载后才出现“Age”文本),上面的单次检测就不够用了。这时候可以用MutationObserver监听DOM变化,实时检测文本。
实现步骤&代码示例
import WebKit class WebViewController: UIViewController, WKNavigationDelegate, WKScriptMessageHandler { private var webView: WKWebView! private var shareButton: UIBarButtonItem! override func viewDidLoad() { super.viewDidLoad() let webConfig = WKWebViewConfiguration() // 注入监听DOM变化的JS脚本 let observerScript = WKUserScript(source: """ // 监听body下的内容变化 const observer = new MutationObserver(() => { const hasAgeText = document.body.innerText.toLowerCase().includes('age'); // 把检测结果发送给Swift端 window.webkit.messageHandlers.textDetection.postMessage(hasAgeText); }); observer.observe(document.body, { childList: true, subtree: true }); """, injectionTime: .atDocumentEnd, forMainFrameOnly: true) webConfig.userContentController.addUserScript(observerScript) // 添加消息处理器,接收JS发来的结果 webConfig.userContentController.add(self, name: "textDetection") // 初始化WKWebView和分享按钮(同方法1) webView = WKWebView(frame: view.bounds, configuration: webConfig) webView.navigationDelegate = self view.addSubview(webView) shareButton = UIBarButtonItem(barButtonSystemItem: .action, target: self, action: #selector(shareButtonTapped)) shareButton.isEnabled = false shareButton.tintColor = .clear navigationItem.rightBarButtonItem = shareButton // 加载目标网页 if let targetURL = URL(string: "你的目标网页URL") { webView.load(URLRequest(url: targetURL)) } } // 接收JS发来的检测结果 func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) { guard message.name == "textDetection", let containsTargetText = message.body as? Bool else { return } shareButton.isEnabled = containsTargetText shareButton.tintColor = containsTargetText ? nil : .clear } @objc private func shareButtonTapped() { guard let currentURL = webView.url else { return } let activityVC = UIActivityViewController(activityItems: [currentURL], applicationActivities: nil) present(activityVC, animated: true) } }
注意点
- 可以缩小
MutationObserver的监听范围(比如只监听可能出现目标文本的特定元素),避免频繁触发影响性能; - 记得在页面销毁时停止监听,避免内存泄漏(可以在
viewWillDisappear里通过JS发送停止指令)。
内容的提问来源于stack exchange,提问作者iDeveloper
相关产品推荐
相关产品推荐

