首页 文章

当调用didFinishNavigation时,WKWebView没有完成加载--WKWebView中的Bug?

提问于
浏览
19

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

采用的方法:

  • 在UIViewController中定义了WKWebView var

  • 创建了一个名为screen capture()的扩展方法,该方法获取WKWebView的图像

  • 使我的UIViewController实现WKNavigationDelegate

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

  • 在UIViewcontroller中实现了didFinishNavigation委托func,为WKWebView调用了屏幕捕获扩展方法

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

问题:

  • 当我调试i模拟器时,我注意到控件到达didFinishNavigation()函数,即使网站尚未在WKWebView中呈现

  • 相应地,拍摄的图像截图是白色斑点 .

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


更新:添加我用于截取Web视图截屏的截图代码

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
 }

4 回答

  • 1

    WKWebView没有't use delegation to let you know when content loading is complete (that'为什么你找不到适合你目的的委托方法 . 了解WKWebView是否仍在加载的方法是使用KVO(键值观察)来查看其 loading 属性 . 这样,当 loadingtrue 更改为 false 时,您会收到通知 .

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

    enter image description here

  • 13

    对于那些仍在寻找答案的人来说,明显的答案是BS,他只是强迫他的方式让它被接受 .
    "loading"和webView(webView:WKWebView,didFinishNavigation导航:WKNavigation!)都做同样的事情,表明主资源是否已加载 . 现在这并不意味着整个网页/网站都被加载,因为它实际上取决于网站的实施 . 如果它需要加载脚本和资源(图像,字体等)以使其自身可见,那么你真的知道网站何时完全加载 .

  • 9

    这是我解决它的方式:

    class Myweb: WKWebView {
    
        func setupWebView(link: String) {
            let url = NSURL(string: link)
            let request = NSURLRequest(URL: url!)
            loadRequest(request)
            addObserver(self, forKeyPath: "loading", options: .New, context: nil)
        }
    
        override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) {
            guard let _ = object as? WKWebView else { return }
            guard let keyPath = keyPath else { return }
            guard let change = change else { return }
            switch keyPath {
            case "loading":
                if let val = change[NSKeyValueChangeNewKey] as? Bool {
                    if val {
                    } else {
                        print(self.loading)
                        //do something!
                    }
                }
            default:break
            }
        }
    
        deinit {
            removeObserver(self, forKeyPath: "loading")
        }
    }
    

    更新Swift 3.1

    override public func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
    
        guard let _ = object as? WKWebView else { return }
        guard let keyPath = keyPath else { return }
        guard let change = change else { return }
    
        switch keyPath {
        case "loading":
            if let val = change[NSKeyValueChangeKey.newKey] as? Bool {
                //do something!
            }
        default:
            break
        }
    }
    
  • 15

    检查页面内容是否从swift或objective-c加载,尤其是对于具有许多动态内容的非常复杂的页面,这不是一个好的选择 .

    从网页的javascript通知你ios代码的更好方法 . 这使它非常灵活和有效,您可以在加载dom或页面时通知ios代码 .

    您可以在此处查看我的 post 以获取更多信息 .

相关问题