如何计算WKWebView的内容高度?

时间:2015-04-21 09:12:22

标签: wkwebview

对于UIWebView,我们可以通过以下方式获得内容高度:

[webView stringByEvaluatingJavaScriptFromString:@"document.body.offsetHeight"]

但是WKWebView没有这个方法,并且webView.scrollView.contentSize.height不对。

(void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation
    {
    }

感谢您的帮助!

4 个答案:

答案 0 :(得分:9)

我用KVO解决了这个问题。

首先,addObserver for WKWebView的scrollView的contentSize如下:

addObserver(self, forKeyPath: "webView.scrollView.contentSize", options: .New, context: nil)

接下来,收到这样的变化:

override func observeValueForKeyPath(keyPath: String, ofObject object: AnyObject, change: [NSObject : AnyObject], context: UnsafeMutablePointer<Void>) {
    if keyPath == "webView.scrollView.contentSize" {
        if let nsSize = change[NSKeyValueChangeNewKey] as? NSValue {
            let height = nsSize.CGSizeValue().height
            // Do something here using content height.
        }
    }
}

很容易获得webview的内容高度。

不要忘记删除观察者:

removeObserver(self, forKeyPath: "webView.scrollView.contentSize", context: nil)

我在deinit中对这一行作了表示。

答案 1 :(得分:2)

你可以这样:

self.webview.navigationDelegate = self;

- (void)webView:(WKWebView *)webview didFinishNavigation:(WKNavigation *)navigation{
     // webview.scrollView.contentSize will equal {0,0} at this point so wait
     [self checkIfWKWebViewReallyDidFinishLoading];
}


- (void)checkIfWKWebViewReallyDidFinishLoading{
      _contentSize = _webview.scrollView.contentSize;
      if (_contentSize.height == 0){
           [self performSelector:@selector(WKWebViewDidFinishLoading) withObject:nil afterDelay:0.01];
      }
}

答案 2 :(得分:2)

修改

为了获得最佳的身高计算,最后我做了一些事情以获得最佳身高:

  1. 我将webview的大小设置得非常大,然后加载内容。
  2. 加载内容后(KVO通知)我使用以下方法调整视图大小。
  3. 然后我再次运行尺寸功能 ,我得到一个新的尺寸并再次调整我的视图。
  4. 以上为我获得了最准确的结果。

    <强> ORIGINAL:

    我已经尝试过滚动视图KVO,我尝试使用clientHeightoffsetHeight等来评估文档上的javascript ...

    最终对我有用的是:document.body.scrollHeight。或者使用最顶层元素的scrollHeight,例如容器div

    我使用KVO听取loading WKWebview属性更改:

    [webview addObserver: self forKeyPath: NSStringFromSelector(@selector(loading)) options: NSKeyValueObservingOptionNew context: nil];
    

    然后:

    - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context {
        if(object == self.webview && [keyPath isEqualToString: NSStringFromSelector(@selector(loading))]) {
            NSNumber *newValue = change[NSKeyValueChangeNewKey];
            if(![newValue boolValue]) {
                [self updateWebviewFrame];
            }
        }
    }
    

    updateWebviewFrame实施:

    [self.webview evaluateJavaScript: @"document.body.scrollHeight" completionHandler: ^(id response, NSError *error) {
         CGRect frame = self.webview.frame;
         frame.size.height = [response floatValue];
         self.webview.frame = frame;
    }];
    

答案 3 :(得分:0)

WKWebView didn't finish loading, when didFinishNavigation is called - Bug in WKWebView? WKWebView不会使用委派来告知您内容加载完成的时间。 您可以创建一个新线程来检查WKWebView的状态。

override func viewDidLoad() {
    super.viewDidLoad()
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0), {  
        while(self.webView?.loading == true){
            sleep(1)
        }            
        dispatch_async(dispatch_get_main_queue(), {
            print(self.webView!.scrollView.contentSize.height)
        })
    })
}