iOS WKWEBVIEW在有嵌入式推文时会计算高度



我的应用使用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
                }
            }
        })
    }
}

希望这也会对其他人有所帮助。

最新更新