如何确定WKWebView的内容大小?


69

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

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

我尝试过sizeToFit和sizeThatFits没有成功。这是我的代码,该代码创建WKWebView实例并将其添加到容器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方法:

- (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。


更新:我仍在寻找解决方案。如果我通过[self.mWebView loadRequest:req]加载远程内容,则可以通过didFinishNavigation中的self.mWebView.scrollView.contentSize获得大小。但是,如果我通过[self.mWebView loadHTMLString:s]加载内容,则该大小要到某个时候才可用。将loadRequest与dataURL一起使用不能解决问题。我不知道什么时候以后。
马克·史密斯

1
我想知道是否会有有意义的答案?考虑一下,网页在任何时候都可能将其内容的大小调整为其窗口的大小,那么怎么可能将窗口的大小更改为其内容的大小呢?我认为WKWebView不提供internalContentSize是有原因的,根本就没有单一的,有意义的“内在”大小。
wardw

Answers:


118

我想我已经阅读了有关该主题的所有答案,而我所拥有的只是解决方案的一部分。我大部分时间都在尝试实现@davew所描述的KVO方法,这种方法偶尔会起作用,但是大部分时间在WKWebView容器的内容下方留有空白。我还实现了@David Beck建议,并将容器高度设置为0,从而避免了如果容器高度大于内容容器高度时出现问题的可能性。尽管如此,我偶尔还是有空白。因此,对我来说,“ contentSize”观察者有很多缺陷。我没有很多Web技术方面的经验,因此我无法回答此解决方案的问题,但是我看到,如果我只在控制台中打印高度,但不对其进行任何操作(例如,调整约束大小),它跳到某个数字(例如 5000),然后转到最高的那一个之前的数字(例如2500-原来是正确的数字)。如果我将高度约束设置为从“ contentSize”获得的高度,则它将自身设置为获取的最大数字,并且永远不会将其大小调整为正确的数字-再次由@David Beck评论提到。

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

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

        })
}

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

事实证明,didFinish导航方法从未在我需要的时候被调用,但是设置了document.readyState步骤之后,下一个(document.body.offsetHeight)在正确的时刻被调用,并向我返回正确的高度数字。


5
document.body.scrollHeight根据此要点答案,您可能想要使用
Zev Eisenberg

4
在我的情况下不起作用,document.body.offsetHeight或者document.body.scrollHeight两者都给错了高度
Ratul Sharker

34
我已经使其与上面的代码一起使用,但是仅在将一些元数据添加到我的html字符串中之后:<meta name =“ viewport” content =“ width = device-width,initial-scale = 1”>
andrei

1
对我来说WKWebViewdocument.body.offsetHeight返回错误的高度,为什么?stackoverflow.com/questions/54187194/...
亚诺什

16
对于iOS 13 document.body.scrollHeight无法正常工作,因此我使用document.documentElement.scrollHeight及其适用于我
Chirag Kothiya

27

您可以使用键值观察(KVO)...

在您的ViewController中:

- (void)viewDidLoad {
    ...
    [self.webView.scrollView addObserver:self forKeyPath:@"contentSize" options:NSKeyValueObservingOptionNew context:nil];
}


- (void)dealloc
{
    [self.webView.scrollView removeObserver:self forKeyPath:@"contentSize" context:nil];
}


- (void)observeValueForKeyPath:(NSString *)keyPath
                      ofObject:(id)object
                        change:(NSDictionary *)change
                       context:(void *)context
{
    if (object == self.webView.scrollView && [keyPath isEqual:@"contentSize"]) {
        // we are here because the contentSize of the WebView's scrollview changed.

        UIScrollView *scrollView = self.webView.scrollView;
        NSLog(@"New contentSize: %f x %f", scrollView.contentSize.width, scrollView.contentSize.height);
    }
}

这样可以节省JavaScript的使用,并让您随时了解所有更改。


5
这有一个缺点:如果内容更改为小于Web视图的高度,则contentSize将与Web视图的框架相同。
大卫·贝克

11
自ios 10.3起,使用这种确定的KVO导致长的空白页结束。有人对此情况有解决方案吗?
Raditya Kurnianto

17

我最近不得不亲自处理这个问题。最后,我对Chris McClenaghan提出解决方案进行了修改。

实际上,他的原始解决方案非常好,并且可以在大多数简单情况下使用。但是,它仅对带有文本的页面有效。它也可能适用于具有静态高度图像的页面。但是,当图像的大小由max-heightmax-width属性定义时,它绝对不起作用。

这是因为加载页面可以调整这些元素的大小。因此,实际上,返回的高度onLoad始终是正确的。但这仅适用于该特定实例。解决方法是监视body高度的变化并对其进行响应。

监控大小调整 document.body

var shouldListenToResizeNotification = false
lazy var webView:WKWebView = {
    //Javascript string
    let source = "window.onload=function () {window.webkit.messageHandlers.sizeNotification.postMessage({justLoaded:true,height: document.body.scrollHeight});};"
    let source2 = "document.body.addEventListener( 'resize', incrementCounter); function incrementCounter() {window.webkit.messageHandlers.sizeNotification.postMessage({height: document.body.scrollHeight});};"
    
    //UserScript object
    let script = WKUserScript(source: source, injectionTime: .atDocumentEnd, forMainFrameOnly: true)
    
    let script2 = WKUserScript(source: source2, injectionTime: .atDocumentEnd, forMainFrameOnly: true)
    
    //Content Controller object
    let controller = WKUserContentController()
    
    //Add script to controller
    controller.addUserScript(script)
    controller.addUserScript(script2)
    
    //Add message handler reference
    controller.add(self, name: "sizeNotification")
    
    //Create configuration
    let configuration = WKWebViewConfiguration()
    configuration.userContentController = controller
    
    return WKWebView(frame: CGRect.zero, configuration: configuration)
}()

func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
    guard let responseDict = message.body as? [String:Any],
    let height = responseDict["height"] as? Float else {return}
    if self.webViewHeightConstraint.constant != CGFloat(height) {
        if let _ = responseDict["justLoaded"] {
            print("just loaded")
            shouldListenToResizeNotification = true
            self.webViewHeightConstraint.constant = CGFloat(height)
        }
        else if shouldListenToResizeNotification {
            print("height is \(height)")
            self.webViewHeightConstraint.constant = CGFloat(height)
        }
        
    }
}

到目前为止,这种解决方案是我能想到的最优雅的解决方案。但是,您应该注意两件事。

首先,在加载网址之前,您应该将设置shouldListenToResizeNotificationfalse。对于加载的URL可以快速更改的情况,需要这种额外的逻辑。发生这种情况时,出于某些原因,旧内容的通知可能会与新内容的通知重叠。为了防止这种行为,我创建了此变量。它确保一旦开始加载新内容,我们就不再处理旧内容中的通知,并且仅在加载新内容后才恢复调整大小通知的处理。

但是,最重要的是,您需要注意以下几点:

如果采用此解决方案,则需要考虑到如果将大小更改WKWebView为通知所报告的大小以外的任何其他内容,则会再次触发通知。

请注意这一点,因为很容易进入无限循环。例如,如果您决定通过使您的身高等于报告的身高+一些额外的填充物来处理通知,则:

func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
        guard let responseDict = message.body as? [String:Float],
        let height = responseDict["height"] else {return}
        self.webViewHeightConstraint.constant = CGFloat(height+8)
    }

如您所见,由于我在报告的高度上增加了8,因此完成后,我的尺寸body将发生变化,并且通知将再次发布。

警惕这种情况,否则就可以了。

并且,如果您发现此解决方案有任何问题,请告诉我-我自己依靠它,因此最好知道是否有一些我没有发现的故障!


Andriy,我再也感谢您了。这样可以省去我几个小时的Google搜索和尝试时间。只是一点点附加信息:这使我可以将meta viewport标记设置为,width=device-width, initial-scale=1.0, shrink-to-fit=no并删除了下的约束设置shouldListenToResizeNotification = true
塔玛斯·森格尔(TamásSengel)

使用这种方法,我也能够使它工作。谢谢!。不过只是好奇,如果有人尝试过此处记录的webview.scrollView.addObserver方法?stackoverflow.com/a/33289730/30363
Blue Waters

1
这可行。记住要通过webView.configuration.userContentController.removeScriptMessageHandler彻底删除它,否则Web视图会保留您的self引用,从而导致内存泄漏。
库纳尔

3
Source2 事件侦听器永远不会被调用,我已经带嵌入的Instagram后,它给我的错误高度每一次的source1
Chlebta

我看到了与Chlebta相同的问题-这对于由于社交嵌入而调整大小的页面不起作用。
扎克

8

为我工作

extension TransactionDetailViewController: WKNavigationDelegate {
    func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
        DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
            self.webviewHeightConstraint.constant = webView.scrollView.contentSize.height
        }
    }
}

此解决方案无法保证调用“ didFinish”后加载将以0.1结尾
Trzy Gracje

搞定了。最佳解决方案。谢谢哥们。
玛尼穆鲁甘

如果我将iPhone从纵向旋转到横向,则其高度会变高
Daniel Springer

7

您还可以通过评估JavaScript获得WKWebView的内容高度。

- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation {
    [webView evaluateJavaScript:@"Math.max(document.body.scrollHeight, document.body.offsetHeight, document.documentElement.clientHeight, document.documentElement.scrollHeight, document.documentElement.offsetHeight)"
              completionHandler:^(id _Nullable result, NSError * _Nullable error) {
                  if (!error) {
                      CGFloat height = [result floatValue];
                      // do with the height

                  }
              }];
}

6

请尝试以下方法。无论在哪里实例化WKWebView实例,都应添加类似于以下内容的内容:

    //Javascript string
    NSString * source = @"window.webkit.messageHandlers.sizeNotification.postMessage({width: document.width, height: document.height});";

    //UserScript object
    WKUserScript * script = [[WKUserScript alloc] initWithSource:source injectionTime:WKUserScriptInjectionTimeAtDocumentEnd forMainFrameOnly:YES];

    //Content Controller object
    WKUserContentController * controller = [[WKUserContentController alloc] init];

    //Add script to controller
    [controller addUserScript:script];

    //Add message handler reference
    [controller addScriptMessageHandler:self name:@"sizeNotification"];

    //Create configuration
    WKWebViewConfiguration * configuration = [[WKWebViewConfiguration alloc] init];

    //Add controller to configuration
    configuration.userContentController = controller;

    //Use whatever you require for WKWebView frame
    CGRect frame = CGRectMake(...?);

    //Create your WKWebView instance with the configuration
    WKWebView * webView = [[WKWebView alloc] initWithFrame:frame configuration:configuration];

    //Assign delegate if necessary
    webView.navigationDelegate = self;

    //Load html
    [webView loadHTMLString:@"some html ..." baseURL:[[NSBundle mainBundle] bundleURL]];

然后添加一个类似于以下方法的方法,该类必须遵守WKScriptMessageHandler协议来处理该消息:

- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {
    CGRect frame = message.webView.frame;
    frame.size.height = [[message.body valueForKey:@"height"] floatValue];
    message.webView.frame = frame;}

这对我有用。

如果您的文档中包含多个文本,则可能需要像这样包装javascript以确保所有内容均已加载:

@"window.onload=function () { window.webkit.messageHandlers.sizeNotification.postMessage({width: document.width, height: document.height});};"

注意:此解决方案不解决文档的持续更新。


userContentController:didReceiveScriptMessage:我收到空字典。:(
Timur Bernikovich '16

它只有当你改变工作document.widthdocument.heightwindow.innerWidthwindow.innerHeight,这就是为什么你得到一个空字典,@TimurBernikowich。
paulvs 2016年

1
对javascript不太了解,但是document.body.scrollHeight对我有用,以获取准确的身高。document.height并且window.innerHeight均为0。window.onload=function () {...}也是必要的。
Ryan Poolos '17

5

您需要等待网络视图完成加载。这是我使用的工作示例

WKWebView内容加载函数永远不会被调用

然后,在webview完成加载后,即可确定所需的高度

func webView(webView: WKWebView!, didFinishNavigation navigation: WKNavigation!) {

   println(webView.scrollView.contentSize.height)

}

3
谢谢!但就我而言,至少didFinishNavigation还为时过早(我得到的大小为0,0)。在WKWebView实例完成其内容的加载之后,我看不到一种简单的调用方法,因此,我将尝试使用JS->本机消息来解决该问题。看来我将需要使用WKUserContentController并实现WKScriptMessageHandler协议。
马克·史密斯

2
这工作正常,但没有什么技巧。您需要再等待十分之一秒才能获得实际的内容大小。
Borut Tomazin

1
不,那解决方案不对。我有0.1个延迟,但在某些情况下还不够。如果您有更多内容,则必须一次又一次地增加延迟。
Makalele,

5

大多数答案都使用“ document.body.offsetHeight”。

这隐藏了身体的最后一个对象。

我通过使用KVO观察器侦听WKWebview“ contentSize”中的更改,然后运行以下代码来解决了这个问题:

self.webView.evaluateJavaScript(
    "(function() {var i = 1, result = 0; while(true){result = 
    document.body.children[document.body.children.length - i].offsetTop + 
    document.body.children[document.body.children.length - i].offsetHeight;
    if (result > 0) return result; i++}})()",
    completionHandler: { (height, error) in
        let height = height as! CGFloat
        self.webViewHeightConstraint.constant = height
    }
)

这不是最漂亮的代码,但是对我有用。


1
此处的JS +1!它处理一个非常重要的边缘情况!对于以前比其内容短(例如具有垂直滚动条)但现在变得更高的Web视图,它可以正确地测量Web视图的高度。当将设备从纵向旋转到横向而您的Web视图突然变宽时,会发生这种情况。在这种情况下,document.body.scrollOffset返回先前(较高)的值,即使内容现在较短(由于宽度增加)并且在底部留有很多空白。我不喜欢KVO方法。didFinish委托方法更加简洁。
m_katsifarakis

4

我发现hlung在这里对WKWebView进行如下扩展是对我来说最简单,最有效的解决方案:

https://gist.github.com/pkuecuekyan/f70096218a6b969e0249427a7d324f91

他的评论如下:

“很好!对我来说,我没有设置webView.frame,而是设置了自动布局内在ContentSize。”

他的代码如下:

import UIKit
import WebKit

class ArticleWebView: WKWebView {

  init(frame: CGRect) {
    let configuration = WKWebViewConfiguration()
    super.init(frame: frame, configuration: configuration)
    self.navigationDelegate = self
  }

  required init?(coder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
  }

  override var intrinsicContentSize: CGSize {
    return self.scrollView.contentSize
  }

}

extension ArticleWebView: WKNavigationDelegate {

  func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
    webView.evaluateJavaScript("document.readyState", completionHandler: { (_, _) in
      webView.invalidateIntrinsicContentSize()
    })
  }

}

3

这是@IvanMih答案的略微修改。对于那些在结束时遇到较大空白的人来说,WKWebview此解决方案对我来说效果很好:

func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
  webView.evaluateJavaScript("document.readyState", completionHandler: { (complete, error) in

    if complete != nil {
      let height = webView.scrollView.contentSize
      print("height of webView is: \(height)")
    }
  })
}

因此,基本上可以使用而不是根据scrollHeight您计算高度来计算高度webView.scrollView.contentSize。我敢肯定在某些情况下这种情况会中断,但是对于静态内容以及如果您要显示所有内容而无需用户滚动,我认为它会做得很好。


2

使用@Andriy的答案,这个答案我能够设置WKWebView中的contentSize的高度并更改它的高度。

这是完整的Swift 4代码:

    var neededConstraints: [NSLayoutConstraint] = []

    @IBOutlet weak var webViewContainer: UIView!
    @IBOutlet weak var webViewHeight: NSLayoutConstraint! {
        didSet {
            if oldValue != nil, oldValue.constant != webViewHeight.constant {
                view.layoutIfNeeded()
            }
        }
    }


   lazy var webView: WKWebView = {
        var source = """
var observeDOM = (function(){
    var MutationObserver = window.MutationObserver || window.WebKitMutationObserver,
        eventListenerSupported = window.addEventListener;

    return function(obj, callback){
        if( MutationObserver ){
            // define a new observer
            var obs = new MutationObserver(function(mutations, observer){
                if( mutations[0].addedNodes.length || mutations[0].removedNodes.length )
                    callback();
            });
            // have the observer observe foo for changes in children
            obs.observe( obj, { childList:true, subtree:true });
        }
        else if( eventListenerSupported ){
            obj.addEventListener('DOMNodeInserted', callback, false);
            obj.addEventListener('DOMNodeRemoved', callback, false);
        }
    };
})();

// Observe a specific DOM element:
observeDOM( document.body ,function(){
    window.webkit.messageHandlers.sizeNotification.postMessage({'scrollHeight': document.body.scrollHeight,'offsetHeight':document.body.offsetHeight,'clientHeight':document.body.clientHeight});
});

"""

        let script = WKUserScript(source: source, injectionTime: .atDocumentEnd, forMainFrameOnly: true)
        let controller = WKUserContentController()
        controller.addUserScript(script)
        controller.add(self, name: "sizeNotification")
        let configuration = WKWebViewConfiguration()
        configuration.userContentController = controller
        let this = WKWebView(frame: .zero, configuration: configuration)
        webViewContainer.addSubview(this)
        this.translatesAutoresizingMaskIntoConstraints = false
        this.scrollView.isScrollEnabled = false
        // constraint for webview when added to it's superview
        neededConstraints += NSLayoutConstraint.constraints(withVisualFormat: "H:|[web]|",
                                                            options: [],
                                                            metrics: nil,
                                                            views: ["web": this])
        neededConstraints += NSLayoutConstraint.constraints(withVisualFormat: "V:|[web]|",
                                                            options: [],
                                                            metrics: nil,
                                                            views: ["web": this])
        return this
    }()


    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        _  = webView // to create constraints needed for webView
        NSLayoutConstraint.activate(neededConstraints)
        let url = URL(string: "https://www.awwwards.com/")!
        let request = URLRequest(url: url)
        webView.load(request)
    }

    func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
        if let body = message.body as? Dictionary<String, CGFloat>,
            let scrollHeight = body["scrollHeight"],
            let offsetHeight = body["offsetHeight"],
            let clientHeight = body["clientHeight"] {
            webViewHeight.constant = scrollHeight
            print(scrollHeight, offsetHeight, clientHeight)
        }
    }

2

经过大量的实验,我设法找到了一个对我有用的解决方案,我发现无需使用javascript即可使webview高度动态化,而且无需从webview中获取高度常数,这就像魅力一样与我一起工作,并且在我注入新的东西时也可以使用样式转换为HTML并使用字体大小和高度

Swift中的代码

1-给您的Webview导航代表

  webView.navigationDelegate = self

2在委派扩展中

extension yourclass : WKNavigationDelegate {
      func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
        // Handel Dynamic Height For Webview Loads with HTML
       // Most important to reset webview height to any desired height i prefer 1 or 0  
        webView.frame.size.height = 1
        DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
        // here get height constant and assign new height in it 
            if let constraint = (webView.constraints.filter{$0.firstAttribute == .height}.first) {
                constraint.constant = webView.scrollView.contentSize.height
            }
 }

希望它也能与你们一起工作**请注意,这不是我在StackOverflow和其他站点上进行了大量搜索的全部工作,而这最终也通过大量测试与我合作


1

我试图滚动视图志愿,我已经试过在文档评估JavaScript的使用clientHeightoffsetHeight等...

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

loading使用KVO收听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;
}];

1

我在UITableViewCell中尝试了Javascript版本,它运行良好。但是,如果要将其放在scrollView中。我不知道为什么,高度可以更高但不能更短。但是,我在这里找到了UIWebView解决方案。https://stackoverflow.com/a/48887971/5514452

它也可以在WKWebView中使用。我认为问题是因为WebView需要重新布局,但不知何故它不会缩小而只能放大。我们需要重置高度,它肯定会调整大小。

编辑:设置约束后,我重置了框架高度,因为有时由于将框架高度设置为0而无法使用。

func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
    self.webView.frame.size.height = 0
    self.webView.evaluateJavaScript("document.readyState", completionHandler: { (complete, error) in
        if complete != nil {
            self.webView.evaluateJavaScript("document.body.scrollHeight", completionHandler: { (height, error) in
                let webViewHeight = height as! CGFloat
                self.webViewHeightConstraint.constant = webViewHeight
                self.webView.frame.size.height = webViewHeight
            })
        }
    })
}

该解决方案极大数我试过的,self.webView.frame.size.height = 0是唯一奏效
丹尼尔·斯普林格

1

还尝试实现不同的方法,最后得出了解决方案。结果,我制作了一个自调整大小的WKWebView,使它的internalContentSize适应其内容的大小。因此,您可以在“自动布局”中使用它。作为示例,我做了一个视图,它可以帮助您在iOS应用上显示数学公式:https : //github.com/Mazorati/SVLatexView


0

对于Webkit中的任何内容,以下代码对我而言都是完美的。确保将以下委托添加到您的类:WKNavigationDelegate。

func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
        DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
        self.bodyWebView.evaluateJavaScript("document.readyState", completionHandler: { (complete, error) in
            if complete != nil {
                self.bodyWebView.evaluateJavaScript("document.body.scrollHeight", completionHandler: { (height, error) in
                    let heightWebView = height as! CGFloat
                    //heightWebView is the height of the web view
                })
            }
        })
    }
}

分发很重要,因为这样可以确保在加载Web视图结束时获得的高度正确,这是由于html可能具有的元素类型而发生的。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.