6

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

- (UIImage *)screenshot
{
    UIImage *screenshot;

    UIGraphicsBeginImageContext(self.frame.size);

    [self.layer renderInContext:UIGraphicsGetCurrentContext()];

    screenshot = UIGraphicsGetImageFromCurrentImageContext();

    UIGraphicsEndImageContext();

    return screenshot;
}
4

7 回答 7

4

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

UIGraphicsBeginImageContextWithOptions(view.bounds.size, YES, 0);
[view drawViewHierarchyInRect:view.bounds afterScreenUpdates:YES];
UIImage* uiImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
于 2015-05-21T02:28:23.563 回答
3

WKWebView 仍然存在一个错误,但您可以通过使用另一个函数来解决它:

[webView snapshotViewAfterScreenUpdates:NO or YES];

有用。

于 2014-11-19T13:41:26.073 回答
2

请参考这个答案

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
            }
        }
    }
于 2018-06-21T07:08:52.590 回答
1

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

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

于 2016-11-02T00:08:26.003 回答
1

这是我的两点。在 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 不在视图层次结构中,我使用保存的快照。
于 2017-04-21T13:05:56.417 回答
0

我让它工作了,但需要以下东西:

  • WKWebView必须在视图层次结构上,例如将其添加到根视图控制器,将其发送到后面,和/或隐藏它直到您需要它
  • yourWebView.frame必须包含全部内容才能工作,我做到了yourWebView.frame = yourWebView.scrollView.contentSize
  • 如果您发现自己要裁剪图像的某些部分,则设备的内存有一个奇怪的限制,请尝试将框架强制设置为更大或荒谬的尺寸,例如 10000 点,然后尝试再次渲染。
  • 委托方法有时会在didFinish真正的绘图发生之前被调用,当你绘图时还没有任何东西,我通过在短暂延迟后调用绘图例程来解决它perform(#selector(process(webView:)), with: webView, afterDelay: 0.01)
于 2019-09-13T04:29:20.977 回答
-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];
}
}
于 2014-11-10T13:04:38.237 回答