简体   繁体   English

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

[英]UIWebview Screen Shot after executing injected JavaScript on the page

What is the best approach for handling the following. 处理以下内容的最佳方法是什么? I have an HTML page with some JavaScript which I load into UIWebview control. 我有一个包含一些JavaScript的HTML页面,并将其加载到UIWebview控件中。 I would like to invoke a js function on the page which mutates the DOM, and after the DOM mutation I would like to capture a screenshot of the webpage. 我想在更改DOM的页面上调用js函数,在DOM更改后,我想捕获网页的屏幕截图。 The problem I am facing is that the image captured from the UIWebview does not represent the current state of the html page. 我面临的问题是,从UIWebview捕获的图像不代表html页面的当前状态。 It represents the state of the DOM prior to the invocation of the [myWebview stringbyevaluatingjavascriptfromstring:@"myHandle.func()"]; 它表示通过调用[myWebview stringbyevaluatingjavascriptfromstring:@"myHandle.func()"];来调用[myWebview stringbyevaluatingjavascriptfromstring:@"myHandle.func()"];之前DOM的状态[myWebview stringbyevaluatingjavascriptfromstring:@"myHandle.func()"]; from below. 从下面。

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

I believe that the problem is related to the fact that the Native UI updates are not updated until the end of the current Run Loop. 我认为该问题与以下事实有关:本机UI更新直到当前运行循环结束才更新。 Therefor the UIWebView does not reflect the current state of the DOM at the point of screen capture. 因此,UIWebView不能在屏幕捕获时反映DOM的当前状态。

I have managed to get the functionality I seek working via the following two approaches. 通过以下两种方法,我设法获得了想要的功能。 Calling both immediately after 之后都立即呼叫

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

1. 1。

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

where createWebViewImage simply holds the following logic 其中createWebViewImage仅包含以下逻辑

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

2. 2。

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];
   });
});

Theses two methods do work in my small test case although I am extremely apprehensive about using them as I am afraid of a case where they may fail. 尽管我非常担心使用它们,这两种方法在我的小型测试用例中确实有效,因为我担心它们可能会失败。

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

Below is the best approach I have been able to come up with 以下是我想出的最佳方法

CFRunLoopObserverRef observer = CFRunLoopObserverCreateWithHandler(kCFAllocatorDefault, kCFRunLoopAfterWaiting, NO, 0, ^(CFRunLoopObserverRef observer, CFRunLoopActivity activity)
{

     [self createWebviewImage];


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

This approach adds an observer to the Main Run loop to be executed during the kCFRunLoopAfterWaiting stage which as mentioned in the reference all UI operations execute during the kCFRunLoopBeforWaiting stage. 这种方法将观察者添加到要在kCFRunLoopAfterWaiting阶段执行的Main Run循环中,如参考文献中所述,所有UI操作都在kCFRunLoopBeforWaiting阶段执行。 Hope this helps someone else. 希望这对其他人有帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM