2009-06-01 14 views
8

Tengo una aplicación que usa UIWebViews en varios controladores de vista. El UIWebViews se utiliza para procesar html generado localmente, no se requiere un acceso de red lento.Deferir viewWillAppear until webViewDidFinishLoad

Para guardar la memoria, solo la carga a petición, como lo indica el control de vista viewWillAppear de devolución de llamada. (Y descargue instancias fuera de pantalla en respuesta a los mensajes didReceiveMemoryWarning.)

El problema es que el usuario puede ver el html que se está procesando, a veces acompañado de flashes de estilo y otros artefactos desagradables surtidos. Preferiría que la representación se realice fuera de la pantalla y revelar la vista completa cuando esté lista.

Sería muy ordenado poder hacer que el viewWillAppear no regrese hasta que el UIWebView esté completamente renderizado. ¿Pero cómo?

Digo al UIWebView qué procesar enviándole un mensaje de loadHTMLString:baseURL:. Esto es asincrónico, y en algún momento (pronto) más tarde se vuelve a llamar al delegado de la vista web webViewDidFinishLoad.

Experimenté con ejecutar un runloop dentro de viewWillAppear, ejecutando NSDefaultRunLoopMode o UITrackingRunLoopMode. Esto funciona en el simulador (que se queja en el registro

[Sincronizar CATransaction] llamado dentro de la transacción

pero hace el trabajo), pero en un dispositivo que bloquea al principio, con webViewDidFinishLoad no ser llamado.

(También, parece que la propiedad de carga UIWebView no funciona. Por lo menos, después de que yo llamo loadHTMLString:baseURL: y antes de obtener la devolución de llamada no es cierto.)

+0

La propiedad "cargar" funciona, pero la carga solo se desencadena una vez que UIWebView está en la pantalla (si rastreas 'webViewDidStartLoad' y' webViewDidFinishLoad'). Las sugerencias tienden a decir "agréguela a la pantalla con una opacidad de 0.01", pero eso no ayuda con un controlador de visualización que aún no se muestra en la pantalla .... –

Respuesta

3

Un montón de soluciones aquí creo. Uno rápido es cargar su UIWebView con su propiedad oculta establecida en SÍ. A continuación, establezca su UIViewController como el delegado UIWebViews e implementar:

- (void)webViewDidFinishLoad:(UIWebView *)webView

donde se define la propiedad de nuevo a NO.

Una cosa a tener en cuenta es que webViewDidFinishLoad se activará más de una vez si tiene contenido enmarcado/incrustado. Entonces tienes que hacer un seguimiento de esto. Realmente no debería ser un problema si está cargando contenido local.

+0

Esta solución hace que el usuario mire una pantalla en blanco mientras la página está dibujado fuera de pantalla. (Para mi aplicación tengo un fondo en el que la página transparente se mostrará al frente, así que eso es algo a mirar, pero ...) Sería mejor modelar otras aplicaciones que muestren el elemento de control (elemento de lista o botón) presionado mientras se procesa la página, y solo entonces tiene animada la vista completamente renderizada. – cluesque

+0

Luego haga que el destino/selector del botón controle la representación y avance la página cuando finalice (webViewDidFinishLoad: como sugiere monowerker) –

+0

webViewDidFinishLoad: no se ejecutará hasta que UIWebView se mueva a la pantalla .... –

0

Me gusta mejor la solución de monowerker, pero otra solución sería mantener el UIWebView ya renderizado todo el tiempo (en un objeto más permanente que el controlador de vista). Solo lo haría si el aspecto de la solución de Monowerker es demasiado perturbador.

+0

El UIWebView consume mucha memoria y es lo primero que se arroja al mar cuando recibimos una advertencia de poca memoria. También uno de mis casos de uso es mostrar detalles de un objeto seleccionado de una vista de lista (por ejemplo, en Correo ves una lista de mensajes, toca uno y lo leo todo) así que no puedo renderizar hasta saber qué objeto es para ser visto. – cluesque

Cuestiones relacionadas