iOS使用嵌入的推文计算html字符串的正确WKWebview高度

时间:2016-06-15 10:29:48

标签: javascript ios twitter wkwebview

我使用wkwebview使用loadHTMLString方法加载给定的HTML字符串。在wkwebview didFinishNavigation之后,我通过评估javascript" document.height"来更新wkwebview的高度到内容高度。 这适用于普通的html字符串。

但是对于html字符串,嵌入的推文高度计算出错了。 这是推文内容

</p>
<blockquote class="twitter-tweet">
<p lang="fr" dir="ltr">Union Cabinet approves civil aviation policy.</p>&mdash; Press Trust of India (@PTI_News) 
<a href="https://twitter.com/PTI_News/status/742990663495647232">June 15, 2016</a></blockquote>
<p>
<script>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"));</script>

因此,在webview完全加载twitter提要后,我们不会在wkwebviewdelegate方法中获得回调。

2 个答案:

答案 0 :(得分:0)

    //Add some Scheme tag in your HTML string. 

    let urlwithScheme = 'widget.twitter.myapp://url’

    let strTwitter = "<script> twttr.ready(function(e){ twttr.events.bind('rendered', function (event) { window.location = \(urlwithScheme); } ); }) </script>"
    let strHTML = "<!DOCTYPE html><html>\(strTwitter)</html>"



    // After load HTML check url scheme, if it belongs to twitter rendered action or not

    @available(iOS 8.0, *)


    func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void){
        // If twitter feed finished renderin
        if(navigationAction.request.url?.scheme == "widget.twitter.myapp"){
            // Don’t update frame here
            decisionHandler(.cancel)
        }

        decisionHandler(.allow)
}

答案 1 :(得分:0)

在这种情况下,最好的解决方案是与观察者一起监听“ contentSize”上的更改。

为此,您将需要以下两个变量:

var observing = false

internal var webViewHeight: CGFloat = 0 {
    didSet {
        guard let webViewHeightConstraint = self.heightConstraint else { return }
        DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
            webViewHeightConstraint.constant = self.webViewHeight
            self.view.layoutSubviews()
            self.delegate?.view.layoutSubviews()
        }
    }
}

asyncAfter方法可以忽略,但是在我看来,没有它就无法很好地更新视图的大小。而且我在底部留有空白。

开始观察和监听更改的方法如下:

func startObservingHeight() {
    let options = NSKeyValueObservingOptions([.new])
    webView?.scrollView.addObserver(self, forKeyPath: "contentSize", options: options, context: nil)
    observing = true
}

func stopObservingHeight() {
    webView?.scrollView.removeObserver(self, forKeyPath: "contentSize", context: nil)
    observing = false
}

override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
    guard let keyPath = keyPath else {
        super.observeValue(forKeyPath: nil, of: object, change: change, context: context)
        return
    }
    switch (keyPath, context) {
    case("contentSize", nil):
        webViewHeight = (webView?.scrollView.contentSize.height)!
    default:
        super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context)
    }
}

如您所见,变量webViewHeight将在收到新值时更新。

在didFinish导航方法中,应为调用先前方法startObservingHeight的观察者开始“侦听”。只要完成Twitter的框架,就会开始更新高度。

func webView(_ webView: WKWebView,
             didFinish navigation: WKNavigation!) {
    indicatorLoading?.stopAnimating()
    webViewHeight = webView.scrollView.contentSize.height
    webView.isHidden = false
    if (!observing) {
        startObservingHeight()
    }
}