WKWebView 没有完成加载,当 didFinishNavigation 被调用时 - WKWebView 中的错误? [英] WKWebView didn't finish loading, when didFinishNavigation is called - Bug in WKWebView?

查看:69
本文介绍了WKWebView 没有完成加载,当 didFinishNavigation 被调用时 - WKWebView 中的错误?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

目标:网站加载完成后截取WKWebView的截图

采用的方法:

  • 在 UIViewController 中定义了一个 WKWebView 变量
  • 创建了一个名为 screen capture() 的扩展方法,用于获取 WKWebView 的图像

  • 让我的 UIViewController 实现 WKNavigationDelegate

  • 设置 wkwebview.navigationDelegate = self(在 UIViewController init 中)

  • 在UIViewcontroller中实现didFinishNavigation委托函数调用WKWebView的截屏扩展方法

<块引用>

func webView(webView: WKWebView, didFinishNavigation 导航: WKNavigation!) {让 img = webView.screenCapture()}

问题:

  • 当我调试模拟器时,我注意到控件到达了 didFinishNavigation() 函数,即使该网站尚未在 WKWebView 中呈现
  • 对应的截图是一个白色的斑点.

我在这里错过了什么?我查看了 WKWebView 的所有可能的委托函数,没有其他东西似乎代表 WKWebView 中内容加载的完成.如果有解决办法,将不胜感激

<小时>

更新:添加我用来截取网页视图屏幕截图的屏幕截图代码

class func captureEntireUIWebViewImage(webView: WKWebView) ->用户界面图像?{var webViewFrame = webView.scrollView.frameif (webView.scrollView.contentSize != CGSize(width: 0,height: 0)){webView.scrollView.frame = CGRectMake(webViewFrame.origin.x, webViewFrame.origin.y, webView.scrollView.contentSize.width, webView.scrollView.contentSize.height)UIGraphicsBeginImageContextWithOptions(webView.scrollView.contentSize, webView.scrollView.opaque, 0)webView.scrollView.layer.renderInContext(UIGraphicsGetCurrentContext())var image:UIImage = UIGraphicsGetImageFromCurrentImageContext()UIGraphicsEndImageContext()webView.scrollView.frame = webViewFrame返回图像}返回零}

解决方案

WKWebView 不使用委托来让您知道内容加载何时完成(这就是为什么您找不到任何适合您目的的委托方法).知道一个 WKWebView 是否还在加载的方法是使用 KVO(键值观察)来观察它的 loading 属性.这样,当 loadingtrue 变为 false 时,您会收到通知.

这是一个循环动画 gif,显示了我测试时会发生什么.我加载一个 web 视图并通过 KVO 响应它的 loading 属性来拍摄快照.上视图是网页视图;较低的(压扁的)视图是快照.如您所见,快照确实捕获了加载的内容:

[NSTimer scheduleTimerWithTimeInterval:1.0 repeats:YES block:^(NSTimer * _Nonnull timer) {if (self->_webKitView.isLoading == true) {NSLog(@"还在加载中...");}别的 {NSLog(@"加载完成...");[定时器失效];dispatch_async(dispatch_get_main_queue(),^{[self->_activityIndi​​cator stopAnimating];});}}];

Goal: To take a screenshot of WKWebView after the website finished loading

Method employed:

  • Defined a WKWebView var in UIViewController
  • Created an extension method called screen capture() that takes image of WKWebView

  • Made my UIViewController to implement WKNavigationDelegate

  • Set the wkwebview.navigationDelegate = self ( in the UIViewController init)

  • Implemented the didFinishNavigation delegation func in UIViewcontroller to call screen capture extension method for WKWebView

func webView(webView: WKWebView, didFinishNavigation navigation: WKNavigation!) {
    let img = webView.screenCapture()
}

Questions:

  • When I debug i simulator, I notice that the control reaches the didFinishNavigation() func even though the website has not yet rendered in the WKWebView
  • Correspondingly the image screenshot taken is a white blob.

What am I missing here? I looked at all possible delegate functions for WKWebView and nothing else seem to represent the completion of content loading in WKWebView. Would appreciate help on if there is a work around


Update: Adding screenshot code that I am using to take a screenshot for web view

class func captureEntireUIWebViewImage(webView: WKWebView) -> UIImage? {

    var webViewFrame = webView.scrollView.frame
    if (webView.scrollView.contentSize != CGSize(width: 0,height: 0)){
    webView.scrollView.frame = CGRectMake(webViewFrame.origin.x, webViewFrame.origin.y, webView.scrollView.contentSize.width, webView.scrollView.contentSize.height)

    UIGraphicsBeginImageContextWithOptions(webView.scrollView.contentSize, webView.scrollView.opaque, 0)
    webView.scrollView.layer.renderInContext(UIGraphicsGetCurrentContext())
     var image:UIImage = UIGraphicsGetImageFromCurrentImageContext()
     UIGraphicsEndImageContext()

     webView.scrollView.frame = webViewFrame         
     return image
    }

    return nil
 }

解决方案

WKWebView doesn't use delegation to let you know when content loading is complete (that's why you can't find any delegate method that suits your purpose). The way to know whether a WKWebView is still loading is to use KVO (key-value observing) to watch its loading property. In this way, you receive a notification when loading changes from true to false.

Here's a looping animated gif showing what happens when I test this. I load a web view and respond to its loading property through KVO to take a snapshot. The upper view is the web view; the lower (squashed) view is the snapshot. As you can see, the snapshot does capture the loaded content:

[NSTimer scheduledTimerWithTimeInterval:1.0 repeats:YES block:^(NSTimer * _Nonnull timer) {
    if (self->_webKitView.isLoading == true) {
        NSLog(@"Still loading...");
    }else {
        NSLog(@"Finished loading...");
        [timer invalidate];
        dispatch_async(dispatch_get_main_queue(), ^{
            [self->_activityIndicator stopAnimating];
        });
    }
}];

这篇关于WKWebView 没有完成加载,当 didFinishNavigation 被调用时 - WKWebView 中的错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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