2010-05-10 10 views
6

Dans mon code, je suis en train de montrer un UIWebView comme chargement d'une page, puis, quand il est fait, capturer une image de la vue Web pour mettre en cache et affiche plus tard (donc je n'ai pas de recharger et de rendre la page Web).Comment puis-je savoir quand un UIWebView a fini de dessiner dans un contexte?

J'ai quelque chose le long des lignes de:

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

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

Le problème que je suis en cours d'exécution en est que, en raison de carrelage de UIWebView, parfois seulement la moitié de la page est rendue dans le contexte du temps Je capture l'image.

Existe-t-il un moyen de détecter ou de bloquer sur le thread de rendu en arrière-plan de UIWebView afin que je puisse obtenir l'image uniquement après que tout le rendu est terminé?


MISE À JOUR: Il se peut que les conditions de course de fil étaient un hareng rouge (on ne sait pas de la documentation, en tout cas, que ce soit la couche personnalisée de UIWebView ou CATiledLayer en blocs généraux sur ses fils de fond) .

Cela peut avoir été un problème d'invalidation (malgré plusieurs types d'appels à setNeedsDisplay à la fois sur le UIWebView et sa couche). Modification des limites du UIWebView avant de le restituer semble avoir éliminé le problème « ne dessine pas la chose ».

J'ai toujours rencontré un problème où quelques tuiles étaient dessinées à l'ancienne échelle, mais appeler deux fois renderInContext: semble avoir suffisamment atténué cela.

Répondre

0

UIWebView utilise probablement un dérivé de CATiledLayer ou sur mesure. Vous pouvez peut-être remplacer le calque par un élément de votre choix, par exemple un CALayer simple qui ne fait pas de dessin avec filetage. Remplacez la couche avant de commencer le chargement du contenu.

Si le remplacement de la couche avec une CALayer standard ne fonctionne pas, vous devrez peut-être créer votre propre sous-classe qui émule le comportement d'une CATiledLayer sans être réellement threadée.

Edit:

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

Ainsi, vous pouvez simplement être en mesure de mettre le contenu à zéro avant d'appeler renderInContext: