WKWebView没有完成加载,当didFinishNavigation被调用 – 在WKWebView中的错误?
目标:在网站加载完成后截取WKWebView
采用的方法:
- 在UIViewController中定义了一个WKWebView var
-
创build了一个名为screen capture()的扩展方法,它可以获取WKWebView的图像
-
使我的UIViewController实现WKNavigationDelegate
-
设置wkwebview.navigationDelegate = self(在UIViewController init中)
-
在UIViewcontroller中实现了didFinishNavigation委托func来调用WKWebView的屏幕截图扩展方法
func webView(webView: WKWebView, didFinishNavigation navigation: WKNavigation!) { let img = webView.screenCapture() }
问题:
- 当我debugging我模拟器,我注意到控制达到didFinishNavigation()func,即使网站还没有在WKWebView呈现
- 相应地,所拍摄的图像截图是一个白色的斑点。
我在这里错过了什么? 我查看了WKWebView的所有可能的委托function,而没有其他东西看起来代表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 }
WKWebView不使用委托让你知道什么时候内容加载完成(这就是为什么你找不到适合你的目的的委托方法)。 知道WKWebView是否还在加载的方法是使用KVO(键值观察)来观察它的loading
属性。 这样,您将从true
更改为false
时收到通知。
这里有一个循环的animationgif显示当我testing这个时会发生什么。 我加载一个Web视图,并通过KVO来响应其loading
属性来拍摄快照。 上部视图是Web视图; 较低的(压扁的)视图是快照。 如您所见,快照确实捕获加载的内容:
这是我如何解决它:
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 } }
对于那些仍然在寻找答案的人来说,标记的答案是BS,他只是强迫他接受。
“加载”和webView(webView:WKWebView,didFinishNavigation导航:WKNavigation!)都做同样的事情,指示主资源是否加载。 现在这并不意味着整个网页/网站被加载,因为它确实取决于网站的实施。 如果需要加载脚本和资源(图像,字体等)以使其可见,导航完成后仍然不会看到任何内容,因为网站所做的networking调用不会被webview跟踪,只有导航是跟踪,所以它不会真正知道什么时候网站加载完全。
检查从swift或objective-c加载的页面内容是不是一个好的select,特别是对于具有许多dynamic内容的非常复杂的页面。
一个更好的方式来通知你从网页的JavaScript代码。 这使得它非常灵活和有效,当一个dom或页面被加载时,你可以通知ios代码。
你可以在这里查看我的post以获取更多信息。
所以这些答案都没有为我工作。 这是什么工作。
我使用webView作为我的WKWebView的名称。 改变你用什么。
我用Swift Spinner
这在整个屏幕上创build了一个很好的叠加半透明模式。 加载它在viewDidLoad中是这样的:
SwiftSpinner.show("Doing something cool....")
使用观察者停止如下:
首先,在你的webview方法中join这个…你加载你的URL的地方:
webView?.addObserver(self, forKeyPath: #keyPath(WKWebView.loading), options: .new, context: nil)
这用于观察者:
// To handle spinner stop; was testing other stuff, could simplify override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) { guard let wv = object as? WKWebView else { return } guard let keyPath = keyPath else { return } guard let change = change else { return } print("in observer") switch keyPath { case "loading": // new:1 or 0 if let val = change[.newKey] as? Bool { if val { print("starting animating") /// spinner.startAnimating() } else { if wv.estimatedProgress == 1 { print("finished loading! stop animating spinner") SwiftSpinner.hide() } } } default: break
- UIApplicationBackgroundRefreshStatusDidChangeNotification用法没有相应的委托方法
- 如何在iPhone上的Phonegap中运行后台JavaScript – 用于定时器/秒表?
- SFHFKeychainUtils。 iOS钥匙串。 ARC兼容
- AFNetworkingcaching图像是否自动加载,还是需要手动进行?
- 引用块内的实例variables
- 将cell.section传递给CustomTableCell
- uicollectionview在reloaddata之后立即select一个项目?
- 使用JavaScript和快捷方式JS创建iOS 12快捷方式
- 如何向UIActivityViewController对象添加不同的文本