Piepants Piepants - 1 year ago 77
iOS Question

cancelPreviousPerformRequestsWithTarget not cancelling an outstanding performSelector:withDelay

I am using a

and don't want the navigation bar to appear unless the user taps anywhere on the screen that isn't a link.
So I have this code to display the navigation bar after a delay:

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

I'm not calling
immediately when the tap handler is invoked because the user might have tapped on a link in which case the tap hander is called before
, so if I hid the navigation bar in
it would flash momentarily onto the screen.
So instead I set it to display after a delay which gives time for the following code to execute within
(and if the user didn't tap on a link
isn't called and the navigation bar is displayed, as it should be in that case).

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

However this isn't working, I've increased the delay time to several seconds and can confirm
is getting called before the navigation bar has been displayed, but when the specified time elapses the bar displays.
is having no effect.

Does anybody know why its not working?

Answer Source

In the documentation of that + (void)cancelPreviousPerformRequestsWithTarget:(id)aTarget selector:(SEL)aSelector object:(id)anArgument method there is this sentence :

This method removes perform requests only in the current run loop, not all run loops.

If I'm interpreting it correctly it would mean that you need to cancel your action in the same run loop that you launched it. Which is clearly not what you want to do.

A way to go around this would be to have a flag that showNavigationBar would have to check to see if it should proceed or abort.