Как я могу узнать, когда UIWebView закончил рисование в контексте?

В моем коде я пытаюсь показать UIWebView во время загрузки страницы, а затем, когда это будет сделано, захватить изображение из веб-представления для кеширования и отображения позже (так что мне не нужно перезагружать и отображать веб-страницу ).

У меня есть что-то вроде:

CGContextRef context = CGBitmapContextCreate(…);
[[webView layer] renderInContext:context];

CGImageRef imageRef = CGBitmapContextCreateImage(context);
UIImage *image = [UIImage imageWithCGImage:imageRef];

Проблема, с которой я сталкиваюсь, заключается в том, что из-за мозаики UIWebView иногда только половина страницы отображается в контексте к тому моменту, когда я захватываю изображение.

Есть ли способ обнаружить или заблокировать поток фонового рендеринга UIWebView, чтобы я мог получить изображение только после того, как весь рендеринг будет завершен?


ОБНОВЛЕНИЕ: возможно, что условия гонки потоков были отвлекающим маневром (во всяком случае из документации неясно, блокирует ли пользовательский уровень UIWebView или CATiledLayer в своих фоновых потоках).

Вместо этого это могло быть проблемой аннулирования (несмотря на несколько видов вызовов setNeedsDisplay как на UIWebView, так и на его уровне). Изменение границ UIWebView перед его рендерингом, похоже, устранило проблему «не отрисовывать все».

Я все еще сталкивался с проблемой, когда несколько плиток рисовались в старом масштабе, но двойной вызов renderInContext:, похоже, смягчил это в достаточной степени.


person Fiona Hopkins    schedule 10.05.2010    source источник


Ответы (1)


UIWebView, вероятно, использует CATiledLayer или настраиваемую производную. Вы можете заменить этот слой чем-то по своему выбору, например, простым CALayer, который не выполняет сквозное рисование. Замените слой перед загрузкой содержимого.

Если замена уровня стандартным CALayer не работает, возможно, вам придется создать свой собственный подкласс, который имитирует поведение CATiledLayer без фактического создания потоков.

Редактировать:

С CATiledLayer.h

/* Note: do not attempt to directly modify the `contents' property of
 * an CATiledLayer object - doing so will effectively turn it into a
 * regular CALayer. */

Так что вы можете просто установить значение nil перед вызовом renderInContext:

person drawnonward    schedule 10.05.2010