如何确定WKWebView的内容大小? [英] How to determine the content size of a WKWebView?

查看:580
本文介绍了如何确定WKWebView的内容大小?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在iOS 8及更高版本下运行时用WKWebView实例替换动态分配的UIWebView实例,我找不到确定WKWebView内容大小的方法。

I am experimenting with replacing a dynamically allocated instance of UIWebView with a WKWebView instance when running under iOS 8 and newer, and I cannot find a way to determine the content size of a WKWebView.

我的Web视图嵌入在更大的UIScrollView容器中,因此我需要确定Web视图的理想大小。这将允许我修改其框架以显示其所有HTML内容,而无需在Web视图中滚动,并且我将能够为滚动视图容器设置正确的高度(通过设置scrollview.contentSize)。

My web view is embedded within a larger UIScrollView container, and therefore I need to determine the ideal size for the web view. This will allow me to modify its frame to show all of its HTML content without the need to scroll within the web view, and I will be able to set the correct height for the scroll view container (by setting scrollview.contentSize).

我尝试过sizeToFit和sizeThatFits但没有成功。这是我的代码,它创建一个WKWebView实例并将其添加到容器scrollview:

I have tried sizeToFit and sizeThatFits without success. Here is my code that creates a WKWebView instance and adds it to the container scrollview:

// self.view is a UIScrollView sized to something like 320.0 x 400.0.
CGRect wvFrame = CGRectMake(0, 0, self.view.frame.size.width, 100.0);
self.mWebView = [[[WKWebView alloc] initWithFrame:wvFrame] autorelease];
self.mWebView.navigationDelegate = self;
self.mWebView.scrollView.bounces = NO;
self.mWebView.scrollView.scrollEnabled = NO;

NSString *s = ... // Load s from a Core Data field.
[self.mWebView loadHTMLString:s baseURL:nil];

[self.view addSubview:self.mWebView];

这是一个实验性的didFinishNavigation方法:

Here is an experimental didFinishNavigation method:

- (void)webView:(WKWebView *)aWebView
                             didFinishNavigation:(WKNavigation *)aNavigation
{
    CGRect wvFrame = aWebView.frame;
    NSLog(@"original wvFrame: %@\n", NSStringFromCGRect(wvFrame));
    [aWebView sizeToFit];
    NSLog(@"wvFrame after sizeToFit: %@\n", NSStringFromCGRect(wvFrame));
    wvFrame.size.height = 1.0;
    aWebView.frame = wvFrame;
    CGSize sz = [aWebView sizeThatFits:CGSizeZero];
    NSLog(@"sizeThatFits A: %@\n", NSStringFromCGSize(sz));
    sz = CGSizeMake(wvFrame.size.width, 0.0);
    sz = [aWebView sizeThatFits:sz];
    NSLog(@"sizeThatFits B: %@\n", NSStringFromCGSize(sz));
}

以下是生成的输出:

2014-12-16 17:29:38.055 App[...] original wvFrame: {{0, 0}, {320, 100}}
2014-12-16 17:29:38.055 App[...] wvFrame after sizeToFit: {{0, 0}, {320, 100}}
2014-12-16 17:29:38.056 App[...] wvFrame after sizeThatFits A: {320, 1}
2014-12-16 17:29:38.056 App[...] wvFrame after sizeThatFits B: {320, 1}

sizeToFit调用无效,sizeThatFits始终返回高度为1。

The sizeToFit call has no effect and sizeThatFits always returns a height of 1.

推荐答案

虽然这个问题已经被问了很长时间了,而且作者可能已经开始了,但是我想回答一下,因为可能会有像我这样的人敲打他的我试图找到解决方案。

Although the question have been asked for quite some time now, and the author probably has moved on, i wish to give my answer because there might be someone like me banging his head trying to find the solution.

我想我读到了关于这个主题的每一个答案,我所拥有的只是解决方案的一部分。大部分时间我都试图实现@davew所描述的KVO方法,偶尔会有效,但大部分时间都在WKWebView容器的内容下留下了空白区域。我还实现了@David Beck建议,并将容器高度设为0,从而避免了容器高度大于内容高度时出现问题的可能性。尽管如此,我偶尔会有空白。
所以,对我来说,contentSize观察者有很多缺陷。我没有很多网络技术的经验,所以我无法回答这个解决方案的问题,但我看到如果我只在控制台中打印高度但不对它做任何事情(例如调整约束的大小),它会跳到某个数字(例如5000),然后转到最高数字之前的数字(例如2500 - 结果是正确的数字)。如果我确实将高度约束设置为我从contentSize获得的高度,它将自己设置为它获得的最高数字,并且永远不会调整大小到正确值 - 这也是@David Beck评论所提到的。

I think i read every answer on this subject and all i had was part of the solution. Most of the time i spent trying to implement KVO method as described by @davew, which occasionally worked, but most of the time left a white space under the content of a WKWebView container. I also implemented @David Beck suggestion and made the container height to be 0 thus avoiding the possibility that the problem occurs if the container height is larger that that of the content. In spite of that i had that occasional blank space. So, for me, "contentSize" observer had a lot of flaws. I do not have a lot of experience with web technologies so i cannot answer what was the problem with this solution, but i saw that if i only print height in the console but do not do anything with it (eg. resize the constraints), it jumps to some number (e.g. 5000) and than goes to the number before that highest one (e.g. 2500 - which turns out to be the correct one). If i do set the height constraint to the height which i get from "contentSize" it sets itself to the highest number it gets and never gets resized to the correct one - which is, again, mentioned by @David Beck comment.

经过大量实验,我找到了一个适合我的解决方案:

After lots of experiments i've managed to find a solution that works for me:

func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
    self.webView.evaluateJavaScript("document.readyState", completionHandler: { (complete, error) in
        if complete != nil {
            self.webView.evaluateJavaScript("document.body.offsetHeight", completionHandler: { (height, error) in
                self.containerHeight.constant = height as! CGFloat
            })
        }

        })
}

当然,正确设置约束以使scrollView根据containerHeight约束调整大小非常重要。

Of course, it is important to set the constraints correctly so that scrollView resizes according to the containerHeight constraint.

事实证明,当我需要时,didFinish导航方法永远不会被调用,但是设置了document.readyState步骤,下一个(document.body.offsetHeight) )在合适的时刻调用,返回正确的高度数字。

As it turns out didFinish navigation method never gets called when i wanted, but having set "document.readyState" step, the next one ("document.body.offsetHeight") gets called at the right moment, returning me the right number for height.

希望它也适合你!

这篇关于如何确定WKWebView的内容大小?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆