UIWebview在页面上执行注入的JavaScript后的屏幕截图

UIWebview Screen Shot after executing injected JavaScript on the page

本文关键字:JavaScript 屏幕截图 注入 执行 UIWebview      更新时间:2023-09-26

处理以下问题的最佳方法是什么?我有一个带有一些JavaScript的HTML页面,我将其加载到UIWebview控件中。我想在页面上调用一个 js 函数来改变 DOM,在 DOM 突变之后,我想捕获网页的屏幕截图。我面临的问题是从UIWebview捕获的图像不代表html页面的当前状态。它表示从下面调用[myWebview stringbyevaluatingjavascriptfromstring:@"myHandle.func()"];之前的 DOM 状态。

[myWebview stringbyevaluatingjavascriptfromstring:@"myHandle.func()"];
UIGraphicsBeginImageContext(myWebview .bounds.size);
[myWebview .layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

我认为问题与以下事实有关:本机UI更新直到当前运行循环结束才更新。因此,UIWebView 不反映屏幕捕获点 DOM 的当前状态。

我已经设法通过以下两种方法获得了我寻求的功能。在之后立即调用两者

[myWebview stringbyevaluatingjavascriptfromstring:@"myHandle.func()"];

1.

[self performSelector:@selector(createWebviewImage) withObject:nil afterDelay:0]

其中createWebViewImage只是持有以下逻辑

UIGraphicsBeginImageContext(myWebview .bounds.size);
[myWebview .layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext(); 

阿拉伯数字。

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{    
   // Back to the main thread for a chunk of code
   dispatch_sync(dispatch_get_main_queue(), ^{
       [self createWebviewImage];
   });
});

这两种方法在我的小型测试用例中确实有效,尽管我对使用它们感到非常担心,因为我担心它们可能会失败。

感谢问题 https://stackoverflow.com/a/26301724/680778

以下是我能够想到的最好的方法

CFRunLoopObserverRef observer = CFRunLoopObserverCreateWithHandler(kCFAllocatorDefault, kCFRunLoopAfterWaiting, NO, 0, ^(CFRunLoopObserverRef observer, CFRunLoopActivity activity)
{
     [self createWebviewImage];

});
CFRunLoopAddObserver(CFRunLoopGetMain(), observer, kCFRunLoopCommonModes);

这种方法将观察器添加到要在 kCFRunLoopAfterWait 阶段执行的主运行循环中,如参考中所述,所有 UI 操作都在 kCFRunLoopBeforWait 阶段执行。希望这对其他人有所帮助。