我无法捕获WKWebView的屏幕截图

时间:2014-11-10 12:26:03

标签: ios objective-c iphone uiview wkwebview

我试图捕获WKWebView的屏幕截图,但我的方法无法正常工作,它返回一个纯色,好像图层树是空的,而它似乎适用于其他视图。 / p>

- (UIImage *)screenshot
{
    UIImage *screenshot;

    UIGraphicsBeginImageContext(self.frame.size);

    [self.layer renderInContext:UIGraphicsGetCurrentContext()];

    screenshot = UIGraphicsGetImageFromCurrentImageContext();

    UIGraphicsEndImageContext();

    return screenshot;
}

7 个答案:

答案 0 :(得分:4)

Stackoverflow answer在iOS 8上使用WKWebView解决了这个问题,其中[view snapshotViewAfterScreenUpdates:][view.layer renderInContext:]返回纯黑色或白色:

UIGraphicsBeginImageContextWithOptions(view.bounds.size, YES, 0);
[view drawViewHierarchyInRect:view.bounds afterScreenUpdates:YES];
UIImage* uiImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

答案 1 :(得分:3)

WKWebView仍然存在一个错误,但您可以通过使用其他功能来解决它​​:

[webView snapshotViewAfterScreenUpdates:NO or YES];

有效。

答案 2 :(得分:1)

drawViewHierarchyInRect方法将起作用,但会导致屏幕短暂闪烁。

如果您需要高性能(快速捕获多帧),我建议将WKWebView添加到您的窗口某处(即使您将其从具有帧偏移的可见区域推出或使其透明)。我发现renderInContext要快得多,只要视图在窗口的视图层次结构中就可以正常工作。

答案 3 :(得分:1)

请参阅此answer

iOS 11.0及更高版本,Apple提供了以下API来捕获WKWebView的快照。

@available(iOS 11.0, *)
    open func takeSnapshot(with snapshotConfiguration: WKSnapshotConfiguration?, completionHandler: @escaping (UIImage?, Error?) -> Swift.Void)

样品用量:

func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {

        if #available(iOS 11.0, *) {
            webView.takeSnapshot(with: nil) { (image, error) in
                //Do your stuff with image
            }
        }
    }

答案 4 :(得分:0)

以下是我的两点。 iOS 10.3.1之前renderInContext曾经适用于WKWebView。但仅当WKWebView包含在呈现的视图层次结构中时。换句话说,系统正在屏幕上绘制它。

在iOS 10.3.1中,renderInContext对我不起作用。在同一时刻,drawViewHierarchyInRect在iOS 10.3.1中运行良好。 但只有它在视图层次结构中!更糟糕。当我试图获取当前屏幕上未显示的WKWebView的快照时,原始视图变为无效。因此,截屏可以打破WKWebView。

这是我的解决方法。

  1. 每次需要时,我都会使用UIImage保存快照(drawViewHierarchyInRect)。但只有WKWebView出现在屏幕上。
  2. 如果WKWebView不在视图层次结构中,我使用保存的快照。

答案 5 :(得分:0)

我可以使用它,但是需要以下条件:

  • WKWebView必须位于视图层次结构上,例如,将其添加到根视图控制器中,将其发送到后面,和/或隐藏它,直到需要它为止。
  • yourWebView.frame必须包含所有内容,我可以通过yourWebView.frame = yourWebView.scrollView.contentSize
  • 如果发现图像的某些部分被裁剪,则设备的内存存在怪异的限制,请尝试将框架强制为更大或荒谬的大小(例如10000点),然后尝试再次渲染。
  • 有时didFinish委托方法在真正的绘图发生之前被调用,并且当您绘图时还没有任何东西,我通过perform(#selector(process(webView:)), with: webView, afterDelay: 0.01)

答案 6 :(得分:-1)

试试这个

- (IBAction)takeScreenShot:(id)sender {

UIWindow *keyWindow = [[UIApplication sharedApplication] keyWindow];
CGRect rect = [keyWindow bounds];
UIGraphicsBeginImageContext(rect.size);
CGContextRef context = UIGraphicsGetCurrentContext();
[keyWindow.layer renderInContext:context];
UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

UIImageWriteToSavedPhotosAlbum(img, self,
                               @selector(image:didFinishSavingWithError:contextInfo:), nil);

}

- (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error
  contextInfo:(void *)contextInfo
{
// Was there an error?
if (error != NULL)
{
    // Show error message...
    UIAlertView *alertView = [[UIAlertView alloc]initWithTitle:@"Image not Saved" message:@"" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil, nil];
    [alertView show];
}
else  // No errors
{
    // Show message image successfully saved
    UIAlertView *alertView = [[UIAlertView alloc]initWithTitle:@"Image Saved" message:@"This chart has been save to your photos" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil, nil];
    [alertView show];
}
}