我想截取WKWebView
的屏幕截图。我在Web视图加载完成后立即调用方法drawViewHierarchyInRect
(屏幕更新设置为true
) - 为此,我观察了Web视图的loading
属性。但是,我注意到,当Web视图通知我加载已完成时,它实际上并没有在屏幕上显示。这就是屏幕截图始终只是白色的原因。当我在加载后0.5秒拍摄屏幕截图(显然太长)时,屏幕截图显示了所需的结果。我的问题是:我不知道网页视图何时实际显示在屏幕上,我可以将延迟设置为0.05,但我无法确保它每次都能正常工作。因此,我的问题是:当实际显示网络视图并准备好截屏时,如何通知我。
提前致谢!
BTW:我使用Swift 2.0和iOS 9与Xcode 7(官方发布)
答案 0 :(得分:5)
正如我刚才所做的那样,让我知道我尝试了什么,以及我是如何弄明白的。我尝试了几件事,首先是WKUserScript
let webViewUserScript = WKUserScript(
source: "window.onload = function() { webkit.messageHandlers.status.postMessage(\(wkwebView.hashValue)) }",
injectionTime: WKUserScriptInjectionTime.AtDocumentEnd,
forMainFrameOnly: true
)
func userContentController(userContentController: WKUserContentController, didReceiveScriptMessage message: WKScriptMessage){ }
通过
注册时wkwebView.configuration.userContentController.addScriptMessageHandler(self, name: "status")
我觉得一切都准备好了。有时工作,但并非总是如此。
和你一样,我也尝试过添加WKNavigationDelegate并使用
func webView(webView: WKWebView, didFinishNavigation navigation: WKNavigation!) { }
同样,这不起作用。另外,为estimatedProgress值添加观察者
wkwebView.addObserver(self, forKeyPath: "estimatedProgress", options: .New, context: nil)
然后尝试在
中制作屏幕截图override func observeValueForKeyPath(keyPath: String?, ofObject: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) { }
没用。
然而,定期检查webView的内容大小的工作原理是什么。我在userContentController函数中执行了此操作,该函数由WKUserScript调用 - 但您也可以在didFinishNavigation函数中执行此操作,然后只需更改要再次调用的函数。代码如下:
let _contentSize = webview.scrollView.contentSize;
if (_contentSize.height == 0){
dispatch_after(createDispatchTime(0.01), dispatch_get_main_queue()) {
self.userContentController(userContentController, didReceiveScriptMessage: message)
}
return
}
这实际上检查了contentSize height属性,如果它为零,它将每0.01秒再次调用该方法,直到设置该属性。以下是我用于创建屏幕截图的功能
var view : UIView!
if self.useSnapShot {
// Use the snapshot function
view = webView.snapshotViewAfterScreenUpdates(true)
} else {
// Draw the view as UIImage
UIGraphicsBeginImageContextWithOptions(webView.frame.size, false, 0.0)
webView.drawViewHierarchyInRect(webView.frame, afterScreenUpdates: true)
let snapshot = UIGraphicsGetImageFromCurrentImageContext()
view = UIImageView(image: snapshot)
view.frame = webView.frame
}
我已经在设备和模拟器上测试了它,它的工作原理。
修改强>
这里是创建调度时间的功能
private func createDispatchTime(seconds: Double) -> dispatch_time_t{
let delay = seconds * Double(NSEC_PER_SEC)
return dispatch_time(DISPATCH_TIME_NOW, Int64(delay))
}
编辑#2
我创造了一个要点,它表明了我相信的更好的方式 https://gist.github.com/christopherhelf/1640454bcace39a87c93#file-wkwebviewplus-swift
我替换了webviews UIScrollview的setContentSize函数,并通知父类已经进行了更改。