2010-09-26 11 views
11

Quiero acceder/borrar la lista de retroceso como si el UIWebView fuera nuevo de nuevo. ¿Hay alguna API pública o solución alternativa para hacer esto?¿Cómo borrar la lista anterior en UIWebview en iPhone?

que he probado:

while ([webview canGoback]) { 
    [webview goBack]; 
} 

pero que se congele el dispositivo (simulador también).

Respuesta

17

Negación
Al igual que con algo como esto, ten en cuenta que es posible que los resultados no lleguen a la aprobación de la tienda de aplicaciones y es posible que no funcionen en absoluto con futuras revisiones del SDK.


no hay ningún método oficial para hacer esto en el SDK. Sin embargo, si realmente desea borrar el historial de retroceso/avance de UIWebView, puede hacerlo con un poco de profundidad en los marcos privados.

Una forma rápida y sucia para hacerlo (con un montón de advertencias del compilador feos) es el siguiente:

Dado que myUIWebViewInstance es un ejemplo perfectamente normal de UIWebView:

id internalWebView=[[myUIWebViewInstance _documentView] webView];  
[internalWebView setMaintainsBackForwardList:NO]; 
[internalWebView setMaintainsBackForwardList:YES]; 

Hay también el tentador método _clearBackForwardCache en el marco, sin embargo, no pareció hacer mucho cuando le hicieron cosquillas. Simplemente cambiando el boolian funcionó un regalo para mí.

+0

¡Código muy astuto! Queremos que la aplicación ingrese en la tienda de aplicaciones para que esto no nos beneficie. Marque la respuesta correcta porque dijo que no había una forma oficial. Lástima – zsniperx

+9

No hay duda, fui rechazado hoy por usar este código exacto. – bendytree

+5

Apple acaba de rechazar una de mis aplicaciones para usar este marco privado. – Marsman

0

Me imagino que puede romper la historia cargando manualmente algo de HTML ...

Algo así como:

[webview loadHTMLString:@"" baseURL:@""]; 
+0

Hola Colin, gracias por tu respuesta. Tristemente, todavía necesitaría volver a la primera página de la lista para hacer esto. Incluso entonces, solo anulará las páginas después de la primera. Dejando el puño allí – zsniperx

13

Si usted está tratando de "reutilización" un UIWebView existente y desactivar la posibilidad de volver a la página anterior lo que estaba antes, se puede:

  1. Al cargar la nueva solicitud (la uno que el usuario no debe volver a), guardar la URL de la nueva solicitud, por ejemplo, como:

    self.curURL = [NSURL urlWithString:@"http://www.bla.com"];
    [webview loadRequest:[NSURLRequest requestWithURL:curURL]];

  2. supongo que tiene su propio botón de retroceso, por lo que en su método delegado webViewDidFinishLoad, agregar:

    backbttn.enabled = webView.canGoBack && ![[webView.request URL] isEqual: curURL];

De esta manera, el usuario ni siquiera sabrán que el UIWebView puede volver a la página anterior.

+0

Veo lo que quiere decir, pero supongo que esto no se ajusta exactamente a mi situación. Definitivamente sería la respuesta correcta si quiero desactivar la posibilidad de volver. Mi situación es Necesito poner UIWebView en su url raíz para que pueda mostrar una barra de herramientas para ir con él y tener una barra de herramientas separada para cualquier urls en la parte superior. ¡Gracias por su ayuda! – zsniperx

+0

Excelente solución en la mayoría de los casos. Parece que se rompe cuando la URL redirige. ¡Todavía vale la pena votar! – mharper

4

que tuvo éxito (por lo que se puede llamar una solución tal 'éxito') mediante la siguiente línea de código:

[webView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"if(window.history.length > 1) { window.history.go(-(window.history.length - 1)) }; window.setTimeout(\"window.location.replace('%@')\", 300);", targetLocation]]; 

donde targetLocation es la URL deseado como un NSString.

Lo que hace es decirle al navegador que retroceda tanto como el historial y luego, después de un corto tiempo de espera, carga la URL deseada.

Por supuesto, esto no resuelve el problema de la limpieza de la historia hacia adelante pasando (que no necesitaba en mi caso).

+0

Desafortunadamente, esto no funcionará si se ha utilizado anteriormente la navegación programática hacia atrás/adelante: en este caso, 'history.length' ya no está sincronizado con la pila de historial real y mostrará el número de páginas navegadas por el usuario (haciendo clic en enlaces). 'history.length' normalmente será más grande que el número de páginas que puede retroceder, y' history.go (history.length-1) 'está fuera de límites y silenciosamente fallan. –

2

Creo que si se suelta el objeto UIWebView y recrear entonces sería borrar el historial. De hecho, tengo un problema inverso. Mi objeto uiwebview se libera automáticamente durante un evento de memoria baja si está dentro de una vista no visible. Luego tengo que volver a crearlo en viewDidLoad, pero no retiene el historial a partir de ese momento.

0

Recogiendo el enfoque ingenioso de Gilbert: Si se modifica, funciona con redirecciones (algo que hasta ahora no es capaz, como señaló mharper).

Antes de cargar la solicitud, guardar la URL deseada y establecer una variable miembro de booleana llamada _saveURL para indicar que la URL de redireccionamiento será salvo (verá el uso exacto de estas dos variables más adelante):

- (void)my_loadURL:(NSURL *)url 
{ 
    NSURLRequest *request = [NSURLRequest requestWithURL:url]; // create the request 
    [_desiredURL release]; // clear up the previous value (assuming -my_loadURL: may be called multiple times) 
    _desiredURL = [url retain]; // store the desired URL (will be used later) 
    _saveURL = YES; // will also be used later 
    [_webView loadRequest:request]; // start loading the request 
} 

(el caso de compilar en un Saldo de referencias automático (ARC) entorno retener y liberar llamadas por supuesto, no será necesario.)

Ahora en la devolución de llamada delegado -webViewDidFinishLoad:, comprobar para ver si la redirección ya se ha producido probando si la URL de la solicitud actual de la vista web difiere de la URL deseada De ser así, guarde la URL de redireccionamiento en una variable miembro _firstURL. Aquí también es donde _saveURL se pone en marcha. Es para evitar sobrescribir _firstURL cada vez que se llama a este método delegado. Además, habilite o deshabilite los botones hacia atrás y hacia delante tal como lo hacíamos anteriormente.

- (void)webViewDidFinishLoad:(UIWebView *)webView 
{ 
    // grab the URL currently being loaded 
    NSURL *currentURL = [webview.request URL]; 

    // check whether we are supposed to save the redirect URL and 
    // whether redirection has taken place yet 
    if (_saveURL && ![currentURL isEqual:_desiredURL]) { 
     [_firstURL release]; 
     _firstURL = [currentURL retain]; 
    } 

    // adjust the enabled-state of the back and forward buttons just like before 
    _backButton.enabled = _webView.canGoBack && ![currentURL isEqual:_firstURL]; 
    _forwardButton.enabled = _webView.canGoForward; 
} 

(Una vez más, retener y liberación no son necesarios con ARC habilitado.)

Sin embargo, hay una desventaja principal de este método. Solo funciona si sabe con certeza que la URL pasada al my_loadURL: redirigirá. De lo contrario, la variable _firstURL se establecerá de alguna manera. Entonces, si no puede decir si la URL correspondiente se redireccionará, entonces este enfoque no se ajusta a sus necesidades. De todos modos, se ajustaba a mis necesidades, y espero poder ayudar a alguien más también.

Actualización: Se puede mejorar este método dejando caer todo eso se trata de _desiredURL, significado no guardar la URL deseada en -my_loadURL: y en -webViewDidFinishLoad: acaba de decir if(_saveURL). De esta forma, funcionará para sitios web que no redireccionan o redirigen al instante.

0

que he probado casi todas las soluciones publicado sin mucho éxito. Mi caso es para el complemento de teléfono móvil de Childbrowser, pero está basado en el mismo problema, una única instancia de vista web que se usa para mostrar páginas externas en mi aplicación. Cuando muestro una página externa, la vista web mantiene el historial de las páginas anteriores que se muestran. Quise eliminar el historial cuando muestro una nueva página web externa.

Después de algunas investigaciones, he encontrado una solución in this SO post que trabajó para mí.

[webView stringByEvaluatingJavaScriptFromString:@"document.body.innerHTML = \"\";"]; 

En el caso de childbrowser, lo coloqué en el método -(IBAction) onDoneButtonPress:(id)sender, que previamente se inserta una página en blanco para empezar en blanco (pero con botón de retroceso activado).

HTH! Milton.

5

Solo recree la vista web. restablecería todo, incluida la historia.

+0

Lo intenté, pero por alguna razón condujo a tiempos de carga lentos ... – Supertecnoboff

+0

También borra el caché que a veces no quieres hacer. Por ejemplo, cuando desea mantener el contenido de un carrito de compras. –

Cuestiones relacionadas