在我用Swift 2.1编写的iOS应用程序中,我使用WKWebView加载一个HTML字符串,该字符串是使用JSON解析器从wordpress博客加载的。
我实现了委托方法func webView(webView: WKWebView, decidePolicyForNavigationAction navigationAction: WKNavigationAction, decisionHandler: (WKNavigationActionPolicy) -> Void) {
并将WKWebView的导航委托设置为self,以便处理链接按下。
现在,当我打开包含WKWebView的ViewController时,这个委托方法会被调用一次,这是加载webView时所期望的行为 - 所以委托似乎设置得当。
我现在的问题是,大多数时候,webView包含的链接不可点击。当您按下链接时,您通常会看到灰色背景,如下图所示。但大多数时候,当我按下链接时,灰色背景不会出现,所以当我修改时,委托方法不会被调用。这个问题当然不需要对WKNavigationDelegate
的配置错误做些什么,因为有时链接选择正常(大约10%)。
您是否知道为什么链接随机有时无法点击,有时可点击(10%的情况)?
答案 0 :(得分:2)
解决方案是删除contentInset
的使用。遗憾的是,WKWebView
并未设计用于处理它的使用(当contentInset
为负数时),因此我们必须通过简单地向htmlString添加空div
来使用解决方法,就像那样:
<div style='width:100%;height:100px'></div>
如果应更改底部插图而不重新加载整个页面,可以先在底部插入一个巨大的div
,然后通过添加正contentInset
来补偿它。这正是此扩展程序的作用:
extension WKWebView {
/// The maximum possible height of the webView bottom content inset
@nonobjc static let maxBottomHeight: CGFloat = 20000
/// Provides an easy way to set the real bottom inset of the webView. Due to a bug in WKWebView framework, we first insert an emtpy div with the size WKWebView.maxContentSize on the bottom of the webView and compensate it by setting a positive contentInset (should be positive, otherwise the bug will be there again).
func set(bottomInset inset: CGFloat) {
self.scrollView.contentInset.bottom = inset - WKWebView.maxBottomHeight
}
}
不要忘记在html字符串的末尾添加div
:
let htmlFooter = "<div style='width:100%;height:\(String(describing: WKWebView.maxBottomHeight))px'></div></body></html>"
答案 1 :(得分:1)
当您将内容加载到WKWebView时,您可能会为您的网页设置错误的baseURL,并导致链接无效,为了使其正常工作,您应该将baseURL设置为正确的http或https网址内容,对于那些工作链接只是因为他们的href中有完整的URL。
这里是将html文本加载到WKWebView中以说明效果:
webView.loadHTMLString(content, baseURL: NSURL(string: ""));
含量:
<html lang="en"><head><meta name="viewport" content="width=device-width, initial-scale=1"></head>
<body>
<h1> click testing </h1>
<ul>
<li><a href="http://www.w3schools.com">Visit W3Schools</a></li>
<li><a href="/about">Un-Clickable without baseURL</a></li>
<li><a href="about://about">Clickable without baseURL</a></li>
</ul>
</body>
</html>
答案 2 :(得分:1)
我会假设您想要的是在某个地方有一些描述或文字,并允许在文本的某些部分内部进行点击/点击,并且为此您要使用WKWebView
我在很久以前的一些应用程序中也使用WKWebView
解决了这个问题,当然有几个解决方案,它只是其中之一,没有别的。
正如有些人对你说的那样,你可以使用loadHTMLString
函数以JSON或者你想要的方式从你的服务器加载HTML字符串,但HTML格式良好且没有错误非常重要
有关评论的loadHTMLString
功能的一个非常重要的一点 ...您通常会在按下链接时出现灰色背景,如下图所示,如果HTML不具有某种CSS样式,则不会发生这种情况,因为如果不是,它具有任何<a><\a>
的默认样式。
因此,让我们看一下以下代码:
import UIKit
import WebKit
class ViewController: UIViewController, WKNavigationDelegate {
var wkWebView: WKWebView!
override func viewDidLoad() {
super.viewDidLoad()
// The part of the HTMl you want to show
let description = "Let's start to visit the <a href=\"http://www.apple.com/\">Apple</a> website first and then if you want the <a href=\"http://www.w3schools.com\">Developer Apple</a> website."
// The default HTML with body and styles formatted and the description inside using string interpolation.
let htmlString = "<html><head><style type=\"text/css\">body {font-family: \"Lato-Regular\";font-size: 35px;color: #333333;margin: 0;}a {text-decoration: none; color: #999;}</style></head><body>\(description)</body></html>"
let preferences = WKPreferences()
preferences.javaScriptEnabled = false
// Configuration for any preferences you want to set
let configuration = WKWebViewConfiguration()
configuration.preferences = preferences
wkWebView = WKWebView(frame: CGRectMake(5, 35, self.view.bounds.width, self.view.bounds.height), configuration: configuration)
if let theWebView = wkWebView {
theWebView.loadHTMLString(htmlString, baseURL: NSURL())
theWebView.navigationDelegate = self
self.view.addSubview(theWebView)
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func webView(webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
UIApplication.sharedApplication().networkActivityIndicatorVisible = true
}
func webView(webView: WKWebView, didFinishNavigation navigation: WKNavigation!) {
UIApplication.sharedApplication().networkActivityIndicatorVisible = false
}
func webView(webView: WKWebView, didFailProvisionalNavigation navigation: WKNavigation!, withError error: NSError) {
let alert = UIAlertController(title: "Error", message: error.localizedDescription, preferredStyle: .Alert)
alert.addAction(UIAlertAction(title: "Ok", style: .Default) { (UIAlertAction) -> Void in
UIApplication.sharedApplication().networkActivityIndicatorVisible = false
})
presentViewController(alert, animated: true, completion: nil)
}
}
在上面的代码中,我为变量description
设置了一些带有可点击元素的文本,并添加了两个委托方法didStartProvisionalNavigation
和didFinishNavigation
以显示networkActivityIndicatorVisible
in状态栏显示在点击可点击文本时加载页面的一些进度。值得注意的是,在htmlString
变量中,我设置了一些样式以显示<a>
一些颜色和字体,这取决于您。
我也添加了didFailProvisionalNavigation
功能来显示警告,在某些情况下,网址无效,例如新添加的HTTPTransportSecurityLayer
iOS 9只允许 https 在某些情况下,您可以使用它来验证网址并了解错误原因。
结果是普通UIViewController
中的以下文字:
当你点击任何灰色文字时,网址会被加载到同一个WKWebView
中,当然你可以个性化这个以在你做的内部浏览器或其他内容中打开,它& #39;取决于你。
如果您点按 Apple :
,您就可以立即看到结果如果您点击 Developer Apple ,您可以看到警报正在运行,因为 http 协议在iOS 9中的HTTPTransportSecurityLayer
中出错:
如果您需要,我已准备好将项目上传到Github。我希望这能帮到你。