2017-09-05 95 views
1

我的应用使用WKWebView来呈现html字符串。 WkWebView嵌入在scrollView中,因为我有其他几个元素(例如按钮,tableViews)。因此,我需要计算WkWebvView内容的大小,并为此使用evaluateJavaScript(“document.body.scrollHeight”,completionHandler:方法。 每当我在html字符串中嵌入推文时,内容高度计算错误并且我的webview切一块其高度的iOS WKWebView在嵌入鸣叫时计算高度不正确

已鸣叫嵌入这个样子的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,我曾因为计算器来代替规则)

是t这里的东西缺少这个twitter代码,或者我应该在webview方法中设置一些东西?

我试着从这篇文章实施解决方案:iOS Calculate correct WKWebview height for html string with embeded tweet但没有成功,或者至少我能找出答案。

任何意见是赞赏??

更新: 我砍了一点点,发现可怕的解决方法,但它是问题出在哪里的好主角。 这是全功能的,我使用的计算高度:

`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的高度得到正确的计算。

回答

0

随着stackoverflow上的几个帖子(特别是:Twitter Uncaught TypeError: undefined is not a function)和我的同事谁是一个Web开发人员,我设法找到了解决这个问题。 基本上,如果在webview需要加载的html字符串中嵌入了推文,则该脚本将添加到webview配置中。之后,我们应该实现userContentController didReceive消息函数,并且在其中我们应该评估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 
       } 

      } 
     }) 
    } 
} 

希望这将帮助其他人。