[开始之前,应注意,我的问题的part是this帖子的副本,但没有被接受的答案。另外,我还阅读了与我的问题类似但不完全相同的其他几篇SO帖子,例如this和this。
问题:
我使用WKWebView来显示以HTML标记的文本。一些文本包含链接,我想在点击它们时在Safari中打开它们。我已经走了很远,但是我仍然遇到2个主要问题。
1)WKWebView不响应会话的第一次点击,即,必须点击两次被点击的第一个链接才能打开Safari。之后点击任何链接都会立即打开Safari。
2)Safari仅打开所点击的第一个链接的URL。假设正在显示3个URL:A,B和C。如果首先点按A,那么只要初始化WKWebView,点击其他2个URL中的任何一个都会始终将Safari打开到A。如果先点按B,那么Safari只会向B打开,依此类推。
这是我认为与该问题最相关的代码:
class CustomWebView: WKWebView, WKUIDelegate, WKNavigationDelegate {
convenience init() {
let config = WKWebViewConfiguration()
config.dataDetectorTypes = [.all]
self.init(frame: .zero, configuration: config)
navigationDelegate = self
uiDelegate = self
}
func webView(_ webView: WKWebView, decidePolicyFor navigationResponse: WKNavigationResponse, decisionHandler: @escaping (_: WKNavigationResponsePolicy) -> Void) {
decisionHandler(.allow)
}
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (_: WKNavigationActionPolicy) -> Void) {
if let url = navigationAction.request.url {
// Note: url is always that of the first opened link.
UIApplication.shared.open(url, options: [:], completionHandler: nil)
decisionHandler(.cancel)
return
}
decisionHandler(.allow)
}
}
您可以尝试检查操作的类型。
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (_: WKNavigationActionPolicy) -> Void) {
if navigationAction.navigationType == .linkActivated,
let reqURL = navigationAction.request.url {
UIApplication.shared.open(reqURL, options: [:], completionHandler: nil)
decisionHandler(.cancel)
} else {
decisionHandler(.allow)
}
}
但是问题是,许多网站截取了链接元素上的点击动作,以触发JavaScript中的导航。那些最终以decidePolicyFor
导航动作而不是.other
的形式发送到.linkActivated
。