如何判断 UIWebView 何时完成对上下文的绘制?
在我的代码中,我尝试在页面加载时显示 UIWebView
,然后在加载完成后,从 Web 视图中捕获图像以缓存并稍后显示(所以我没有重新加载并呈现网页)。
我有一些类似的事情:
CGContextRef context = CGBitmapContextCreate(…);
[[webView layer] renderInContext:context];
CGImageRef imageRef = CGBitmapContextCreateImage(context);
UIImage *image = [UIImage imageWithCGImage:imageRef];
我遇到的问题是,由于 UIWebView
的平铺,有时在我捕获图像时只有一半页面呈现到上下文中。
有没有办法检测或阻止 UIWebView 的后台渲染线程,以便我只能在所有渲染完成后才能获取图像?
更新:线程竞争条件可能是一个转移注意力的话题(无论如何,从文档中并不清楚,UIWebView
的自定义层还是CATiledLayer
通常会阻塞其后台线程)。
这可能是一个失效问题(尽管在 UIWebView
及其层上对 setNeedsDisplay
进行了多种调用)。在渲染之前更改 UIWebView 的边界似乎消除了“未绘制整个事物”的问题。
我仍然遇到了一个问题,即以旧比例绘制了一些图块,但调用 renderInContext:
两次似乎已经充分缓解了这个问题。
In my code I'm trying to show a UIWebView
as a page is loading, and then, when it's done, capture an image from the web view to cache and display later (so I don't have to reload and render the web page).
I have something along the lines of:
CGContextRef context = CGBitmapContextCreate(…);
[[webView layer] renderInContext:context];
CGImageRef imageRef = CGBitmapContextCreateImage(context);
UIImage *image = [UIImage imageWithCGImage:imageRef];
The problem I'm running into is that, due to UIWebView
's tiling, sometimes only half of the page is rendered to the context by the time I capture the image.
Is there a way to detect or block on UIWebView
's background rendering thread so that I can get the image only after all of the rendering has finished?
UPDATE: It may be that thread race conditions were a red herring (it's unclear from the documentation, at any rate, whether UIWebView
's custom layer or a CATiledLayer
in general blocks on its background threads).
This may instead have been an invalidation issue (despite several sorts of calls to setNeedsDisplay
on both the UIWebView
and its layer). Changing the bounds of the UIWebView
before rendering it appears to have eliminated the "not drawing the whole thing" problem.
I still ran into a problem where a few tiles were being drawn at the old scale, but calling renderInContext:
twice seems to have mitigated that sufficiently.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
UIWebView 可能正在使用 CATiledLayer 或自定义衍生品。您也许可以用自己选择的东西替换图层,例如不执行线程绘制的简单 CALayer。在开始加载内容之前替换图层。
如果用标准 CALayer 替换该层不起作用,您可能必须创建自己的子类来模拟 CATiledLayer 的行为,而无需实际进行线程化。
编辑:
来自 CATiledLayer.h
因此,您可以在调用
renderInContext:
之前将内容设置为 nilUIWebView is probably using a CATiledLayer or custom derivative. You may be able to replace the layer with something of your own choosing such as a simple CALayer which does not do threaded drawing. Replace the layer before you start loading content.
If replacing the layer with a standard CALayer does not work, you may have to make your own subclass that emulates the behavior of a CATiledLayer without actually being threaded.
Edit:
From CATiledLayer.h
So you may just be able to set the contents to nil before calling
renderInContext: