2009-12-03 23 views
16

En mi aplicación de iPhone, tengo un UIWebView donde estoy cargando un html local. Todo funciona bien, pero ahora quiero poder manejar enlaces locales (a notas al pie): cuando hago clic en un enlace local, quiero poder saltar a la nota al pie de página referida por él, y luego poder volver .UIWebView shouldStartLoadWithRequest solo se llamó una vez?

<a href="#tofootnote">jump to footnote</a> 

manejé esto añadiendo mi código para shouldStartLoadWithRequest e interceptar clics de enlace locales; cuando se hace clic en un enlace local, trabajo mi magia (ocultar algunos elementos de la interfaz de usuario, agregar un botón de retroceso, etc.); al hacer clic en el botón Atrás, vuelvo a la ubicación original en el documento html.

El problema es que al hacer clic UNA VEZ MÁS en el enlace ya no se invoca shouldStartLoadWithRequest. Es decir, el código siguiente:

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType { 
NSLog(@"foo bar"); 
return YES; 
} 

sólo muestra "foo bar" ONCE (en realidad, dos veces - la primera vez que estoy cargando inicialmente el documento), pero sólo una vez después, independientemente del número de veces que' m haciendo clic en el enlace local

Entonces, a menos que alguien tenga una mejor explicación, supongo que UIWebView almacena en caché el documento o enlace o algo así y ya no llama al manejador después de la llamada inicial; Si este es el caso, ¿cómo puedo borrar esta caché interna? (sin volver a cargar el documento)

+0

PS. Estoy cargando UIWebView utilizando loadHTMLString (porque necesito configurar el URL baseURL), por lo que no puedo configurar la Política de caché para la solicitud de carga original. – Alex

+0

En realidad, incluso el uso de urlrequest y la política de caché aún no funciona. ¡Ayudame por favor! – Alex

Respuesta

14

La única solución que he encontrado para este problema es reemplazar todas las anclas de "#anchor" a algo que se considera una URL, como "| ancla". De esta manera UIWebView pensará que es un enlace real e intentará la solicitud cuando se haga clic. Obviamente, esta solución solo funcionará si maneja todos los clics usted mismo y, por lo tanto, puede interpretar los anclajes modificados. Puedo entender el motivo del comportamiento de UIWebView, pero es bastante frustrante. El delegado realmente necesita mensajes para hacer coincidir los controladores onclick, etc.

+0

Gracias a esta solución funcionó para mí también – Dilshan

+0

Usted dice que puede entender la razón. ¿Puedes explicar? No puedo entender la razón y, en lo que a mí respecta, es un error en UIWebView. Ya sea que se llame al delegado o no, la vista web debe navegar al enlace especificado cada vez que se hace clic, no solo una vez. – kball

+2

La razón es simple. Técnicamente, las devoluciones de llamada de UIWebView que existen actualmente son para manejar la "recuperación" de las páginas web cliqueadas. Cuando haces clic en un enlace hash, no estás recuperando una página, solo estás navegando en la página actual. Por lo tanto, técnicamente no es un error. A menos que consideres un mal diseño de API como un error. Tiendo a pensar que el mal diseño es un error ... pero reconozco que Apple podría tener una opinión diferente ;-) – GrafikRobot

-1

Intente 'tocar' la etiqueta del anclaje (asígnela a sí misma). Mi hipótesis es que hará que el DOM se actualice, lo que hace que vuelva a verificar el enlace. ¡No lo he probado, es solo una idea!

+0

Tengo exactamente el mismo problema en este momento ... Intenté su solución, y no ayuda. – GrafikRobot

0

Esto parece estar sucediendo para mí también cuando uso un onclick = "window.location.hash = ...; return false;" en lugar de capturar el clic.

Si me desplazo un poco o hago clic en otro delimitador, puedo usar el enlace nuevamente.

-1

NSURLRequest * request = [petición NSURLRequestWithURL: fileURL cachePolocy: NSURLRequestReloadIgnoringLocalCacheData timeoutInterval: 60.0];

[webView loadRequest: request];

+0

Tengo exactamente el mismo problema en este momento ... Y atestiguo que cambiar la opción de política de caché no funciona. – GrafikRobot

0

Si su están cargando el contenido utilizando la loadHTMLString, como:

[webView loadHTMLString:htmlString baseURL:[[NSBundle mainBundle] bundleURL]]; 

Entonces parece ser suficiente sólo para recargar la html-cadena. Al hacer clic en el ancla, (de nuevo) llamará a su gancho de delegado.

1

Un truco que encontré cuando me encontré con este problema usando jquery mobile incrustó cambios en la página fue agregar un número al azar en el hash. De esta manera iOS parece pensar que es una nueva solicitud:

//set location hash to path 
set: function(path) { 
    path += "&" + Math.random(); 
    location.hash = path; 
}, 

Esto debería funcionar ajustando dinámicamente el camino a través de un evento onclick también.

6

Puedo solucionar este problema estableciendo window.location en un ancla ficticia después de manipular la válida.

- (BOOL)webView:(UIWebView *)aWebView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType { 
    if ([[request URL] fragment]) { 
     if ([[[request URL] fragment] isEqualToString:@"__DUMMY_ANCHOR"]) 
      return NO; 

     // Do your custom handling of the anchor here 

     // Change the location to a non-existent anchor 
     [aWebView stringByEvaluatingJavaScriptFromString:@"window.location='#__DUMMY_ANCHOR'"]; 

     return NO; 
    } 
} 
0

Una variación en el código (operativo) de Ben Dolman anterior. "Restablece" el caché de UIWebView con los dos enlaces ficticios para que los enlaces posteriores sigan llamando al método. Primero guarda el enlace interno, o fragmento en un NSString llamado savedFragment. Luego le dice a UIWebview que cargue el primer enlace ficticio #pageX y luego otro #pageY. Finalmente, toma el FragmentoSalvo y lo usa para construir el número de página, que luego se usa en un método separado para desplazar el UIWebview a la ubicación correcta.

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType { 


    if ([[request URL] fragment]) { //check if fragment exists (treat as internal link) 

     NSString *fragment = [[request URL] fragment]; 

     //If the fragment is neither "pageX" nor "pageY", treat as an internal link in the PDF 
     if (![fragment isEqualToString:@"pageX"] && 
      ![fragment isEqualToString:@"pageY"]) { 

      savedFragment = fragment; //hold the fragment in savedFragment (NSString) 
      [pdfWebView stringByEvaluatingJavaScriptFromString:@"window.location='#pageX'"]; //load UIWebView with first dummy link 

     } else if ([fragment isEqualToString:@"pageX"]) { 

      [pdfWebView stringByEvaluatingJavaScriptFromString:@"window.location='#pageY'"]; //load UIWebView with second dummy link 

     } else { 

      NSString *pageString = [savedFragment stringByReplacingOccurrencesOfString:@"page" withString:@""]; //grab the page from savedFragment 
      int page = [pageString intValue]; 
      [self scrollWebViewToPage:page-1]; //scroll to page (seperate method) 
     } 

     return NO; //do not load any of the dummy links 

    } else { 

     return YES; //first load of PDF into UIWebView should be allowed 
    } 

} 
Cuestiones relacionadas