iOS为带有嵌入推文的html字符串计算正确的WKWebview高度
Posted
技术标签:
【中文标题】iOS为带有嵌入推文的html字符串计算正确的WKWebview高度【英文标题】:iOS Calculate correct WKWebview height for html string with embeded tweet 【发布时间】:2016-06-15 10:29:47 【问题描述】:我正在使用 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>— 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 feed 之后,我们不会在 wkwebviewdelegate 方法中得到回调。
【问题讨论】:
嗨,这个问题你解决了吗? 是的,我解决了这个问题。 怎么样,我也有同样的问题。谢谢, 请检查我的答案。 【参考方案1】:在这种情况下,最好的解决方案是通过观察者监听“contentSize”的变化。
为此,您需要以下 2 个变量:
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()
【讨论】:
非常爱你,当你在 wkwebview 中嵌入异步时,这是最好的答案【参考方案2】: //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)
【讨论】:
以上是关于iOS为带有嵌入推文的html字符串计算正确的WKWebview高度的主要内容,如果未能解决你的问题,请参考以下文章