2010-05-10 6 views
6

In meinem Code versuche ich eine UIWebView zu zeigen, wie eine Seite geladen wird, und dann, wenn es fertig ist, ein Bild aus der Webansicht zu cachen und später anzuzeigen (ich muss nicht neu laden und rendern Website).Wie kann ich feststellen, wann ein UIWebView mit dem Zeichnen in einen Kontext fertig ist?

Ich habe etwas entlang der Linien von:

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

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

Das Problem, das ich in laufen lasse, ist, dass aufgrund UIWebView ‚s Fliesen, manchmal nur die Hälfte der Seite auf den Kontext der Zeit gemacht wird Ich nehme das Bild auf.

Gibt es eine Möglichkeit, UIWebView 's Hintergrund Rendering Thread zu erkennen oder zu blockieren, so dass ich das Bild erst erhalten kann, nachdem alle Rendering beendet ist?


UPDATE: Es kann die Thread Rennbedingungen waren werden, um ein Ablenkungsmanöver (es ist unklar, aus der Dokumentation, auf jedem Fall, ob UIWebView ‚s individuelle Schicht oder ein CATiledLayer im allgemeinen Block auf ihren Hintergrund-Threads) .

Dies könnte stattdessen ein Ungültigmachungsproblem sein (trotz mehrerer Arten von Aufrufen an setNeedsDisplay auf der UIWebView und seine Schicht). Das Ändern der Grenzen des UIWebView vor dem Rendern scheint das Problem "das ganze Ding nicht zeichnen" beseitigt zu haben.

Ich lief immer noch in ein Problem, wo ein paar Kacheln im alten Maßstab gezeichnet wurden, aber renderInContext: zweimal zu nennen, scheint das ausreichend gemildert zu haben.

Antwort

0

UIWebView verwendet wahrscheinlich einen CATiledLayer oder ein benutzerdefiniertes Derivat. Möglicherweise können Sie die Ebene durch etwas Ihrer Wahl ersetzen, z. B. einen einfachen CALayer, der keine Gewindezeichnungen ausführt. Ersetzen Sie die Ebene, bevor Sie mit dem Laden von Inhalten beginnen.

Wenn das Ersetzen des Layers durch einen Standard-CALayer nicht funktioniert, müssen Sie möglicherweise eine eigene Unterklasse erstellen, die das Verhalten eines CATiledLayer emuliert, ohne dass tatsächlich Threads verwendet werden.

Edit:

Von 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. */ 

So können Sie nur in der Lage sein, den Inhalt auf Null zu setzen, bevor renderInContext:

Aufruf