2012-01-02 13 views
10

Estoy usando un UIWebView y no quiero que la barra de navegación aparezca a menos que el usuario toque en cualquier parte de la pantalla que no sea un enlace. así que tengo el código para mostrar la barra de navegación después de una demora:cancelPreviousPerformRequestsWithTarget no cancela un destacado performSelector: withDelay

- (void)handleTapGesture:(UITapGestureRecognizer *)sender 
{  
.... 
[self performSelector:@selector(showNavigationBar) withObject:self afterDelay:0.2]; 
} 

no estoy llamando showNavigationBar inmediatamente cuando el manejador del grifo se invoca porque el usuario podría haber pulsado sobre un enlace en cuyo caso el lanzador del grifo se llama antesUIWebViewshouldStartLoadWithRequest, así que si me escondí en la barra de navegación shouldStartLoadWithRequest sería parpadear momentáneamente en la pantalla. Así que en lugar lo fijo para mostrar después de un retraso que le da tiempo para el siguiente código para ejecutar dentro de shouldStartLoadWithRequest (y si el usuario no pulse sobre un enlace shouldStartLoadWithRequest no se llama y la barra de navegación en la pantalla, como debe ser en ese caso).

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType 
{ 
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(showNavigationBar) object:nil]; 
... 

Sin embargo, esto no funciona, he aumentado el tiempo de retardo de varios segundos y puedo confirmar cancelPreviousPerformRequestWithTarget está recibiendo llamadas antes de que se haya mostrado la barra de navegación, pero cuando el tiempo especificado transcurre la barra de pantallas. cancelPreviousPerformRequestWithTarget está teniendo ningún efecto.

¿Alguien sabe por qué no su trabajo?

Respuesta

9

En el documentation de ese + (void)cancelPreviousPerformRequestsWithTarget:(id)aTarget selector:(SEL)aSelector object:(id)anArgument método no es esta frase:

Este método elimina realizar solicitudes sólo en el bucle de ejecución actual, no todos los bucles de ejecución.

Si lo interpreto correctamente, significa que debe cancelar su acción en el mismo ciclo de ejecución que lo lanzó. Lo cual claramente no es lo que quieres hacer.

Una forma de evitar esto sería tener una marca que showNavigationBar tendría que verificar para ver si debería continuar o abortar.

+0

Voy a dar que un intento. ¿Existe una variante de cancelación que funcione para todos los bucles de ejecución? Intenté esto pero tampoco funciona: [[NSRunLoop mainRunLoop] cancelPerformSelector: @selector (showNavigationBar) target: self argument: nil]; – Gruntcakes

+0

@Piepants No lo creo, pero eso no significa que no exista. –

+0

¡Tenía el mismo problema y el marcar es el camino a seguir! – durazno

14

Su rendimiento no coincide con su cancelación. En el realizar estás pasando a sí mismo como el objeto:

[self performSelector:@selector(showNavigationBar) withObject:self afterDelay:0.2]; 

en el nil cancelar estás pasando como objeto:

[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(showNavigationBar) object:nil]; 

no coinciden, por lo que el retraso no debe realizar ser cancelado

+2

Simplemente me gustó eso sin suerte. Así que traté de eliminar todas las solicitudes: [NSObject cancelPreviousPerformRequestsWithTarget: self]; Ahora funciona como un encanto! –

+0

Para ampliar lo que dijo Dave, withObject en la llamada original es para los parámetros del método. Si no hay ninguno, entonces debe ser nulo.Si hay algunos, entonces showNavigationBar necesita dos puntos: después de él y el primer parámetro es el primero conObject. – JScarry

2
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(showNavigationBar) object:self]; 

que trabajó para mí;)

+0

Funcionó para mí como-bien =) –

Cuestiones relacionadas