我的应用使用WKWebView来显示HTML字符串。wkwebview嵌入在卷轴中,因为我还有其他几个元素(例如按钮,tableviews)。因此,我需要计算wkwebvview内容的大小,为此,我使用esturejavascript(" document.body.scrollheight",postermionhandler:method。每当我将Tweet嵌入HTML字符串中时,内容高度就会错误地计算出来,并且我的WebView削减了其高度。
HTML字符串的一部分,其嵌入式嵌入式外观如下:
<blockquote class="twitter-tweet" data-lang="en"><p><a
href="https://twitter.com/hashtag/SYRIA?src=hash">#SYRIA</a> Admiral Essen frigate launched <a href="https://twitter.com/hashtag/Kalibr?src=hash">#Kalibr</a> cruise missiles against ISIS objects near Deir ez-Zor <a href="https://BLABLA*">pic.twitter.com/azHAIii07g</a></p><p>— Минобороны России (@mod_russia) <a href="https://twitter.com/mod_russia/status/905007557554700288">September 5, 2017</a></p></blockquote><p><script src="https://platform.twitter.com/widgets.js"></script>
(Blabla*实际上是T.Co/Azhaiii07g,我由于stackoverflow规则而不得不替换)
此Twitter代码中是否缺少某些内容,或者我应该在WebView方法中设置某些内容?
我尝试从本文中实现解决方案:iOS计算带有嵌入式推文的HTML字符串的正确WKWebView高度,但没有成功,或者至少我可以找出答案。
任何建议将受到赞赏?
更新:我砍了一点,发现了可怕的解决方法,但对于问题所在的位置来说,这是一个很好的领导。这是我用于计算高度的完整功能:
`func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
self.webViewx.evaluateJavaScript("document.readyState", completionHandler: {
[weak self] (complete, error) in
if complete != nil { self?.webViewx.evaluateJavaScript("document.body.offsetHeight", completionHandler: {
[weak self] (height, error) in
})
}`
如果我说:
`DispatchQueue.main.asyncAfter(deadline: DispatchTime.now()+1, execute: {
self?.webViewx.evaluateJavaScript("document.body.offsetHeight", completionHandler: {
[weak self] (height, error) in
print("HEIGHT AFTER 1 sec", height)
})
})`
1秒钟后我得到正确的高度。现在,在正确时间之后获得该高度更新的方法是什么。
另外,一个附带说明,如果我嵌入了Facebook或Instagram帖子,则一切都可以正常工作,并且WebView Height可以正确计算。
借助stackoverflow上的几篇文章(尤其是:Twitter Undfult typeError:Undefined不是函数),我的同事是Web开发人员,我设法找到了这个问题的解决方案。基本上,如果在HTML字符串中有一个嵌入式推文,WebView需要加载,则想法是在WebView配置中添加脚本。之后,我们应该实现USERCONTENTCONTROLLER DODRECEIVE消息功能,在其中我们应该评估WebView的高度。
这是应在WebView.loadhtmlstring方法之前进行的代码:
if htmlString.contains("platform.twitter.com/widgets.js") {
let twitterJS: String = "window.twttr = (function(d, s, id) {var js, fjs = d.getElementsByTagName(s)[0],t = window.twttr || {};if (d.getElementById(id)) return t;js = d.createElement(s);js.id = id;js.src = "https://platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js, fjs);t._e = [];t.ready = function(f) {t._e.push(f);};return t;}(document, "script", "twitter-wjs"));twttr.ready(function (twttr) {twttr.events.bind('loaded', function (event) {window.webkit.messageHandlers.callbackHandler.postMessage('TWEET');});});"
let userScript = WKUserScript(source: twitterJS, injectionTime: .atDocumentEnd, forMainFrameOnly: false)
webViewx.configuration.userContentController.removeAllUserScripts()
webViewx.configuration.userContentController.addUserScript(userScript)
webViewx.configuration.userContentController.add(self, name: "callbackHandler")
}
首先,检查HTML字符串是否具有嵌入式推文的子字符串。分配给Twitterjs的脚本是我们从Twitter网页中获得的。从某种意义上说,最后一行很重要。
实际高度评估是这样完成的:
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
if message.name == "callbackHandler" {
print(message.body)
webViewx.evaluateJavaScript("document.body.offsetHeight", completionHandler: { (height, error) in
if let error = error {
print(error.localizedDescription)
return
}
if let height = height as? CGFloat{
if height > self.kontejnerHeight.constant {
self.kontejnerHeight.constant = height
}
}
})
}
}
希望这也会对其他人有所帮助。