Как я могу узнать, когда UIWebView закончил рисование в контексте? - PullRequest
6 голосов
/ 10 мая 2010

В моем коде я пытаюсь показать 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: дважды, похоже, достаточно смягчил эту проблему.

1 Ответ

0 голосов
/ 10 мая 2010

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

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

Edit:

Из 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. */

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

...