Saturday, 17 August 2013

UIGestureRecognizer with NSTimer that never dies

UIGestureRecognizer with NSTimer that never dies

I'm trying to set up a "FastForward/Next" button in a media player that
can be tapped to move to the next song or held to fast forward within the
current song. Mostly, it works: you can successfully fastforward and
successfully move to the next song, but the thing is, the NSTimer that
makes it work never invalidates, so once you start fastforwarding, you
never stop.
I set up the gesture recognizers in viewDidLoad:
UITapGestureRecognizer *singleTapFastForward = [[UITapGestureRecognizer
alloc] initWithTarget: self action:@selector(nextSong:)];
singleTapFastForward.numberOfTapsRequired = 1;
[_buttonNext addGestureRecognizer:singleTapFastForward];
_holdFastForward = [[UILongPressGestureRecognizer alloc] initWithTarget:
self action:@selector(startFastForward:)];
[_buttonNext addGestureRecognizer:_holdFastForward];
[singleTapFastForward requireGestureRecognizerToFail:_holdFastForward];
and here is the meat of the function:
- (IBAction)startFastForward:(id)sender {
_timerFastForward = [NSTimer scheduledTimerWithTimeInterval:0.5
target:self selector:@selector(executeFastForward) userInfo:nil
repeats:YES];
}
- (void)executeFastForward {
[_avPlayer seekToTime:CMTimeMake(CMTimeGetSeconds([_avPlayer
currentTime]) + 10, 1)];
if(_holdFastForward.state == 0) {
[self endFastForward:self];
}
}
- (IBAction)endFastForward:(id)sender {
[_timerFastForward invalidate];
}
Here's the tricky part: when I set a breakpoint at the
if(_holdFastForward.state == 0) line, it starts working as soon as I let
go of the button (as it should), and it successfully calls the
endFastForward method. By my reckoning, that should kill the timer and end
the whole cycle, but then executeFastForward gets called again, and then
again and again. The invalidate line just seems to do nothing (and there
are no other points in my code that call executeFastForward).
Any ideas? This seems like a simple thing, and if the invalidate line
worked everything would be perfect. I just don't know why
executeFastForward continues to be called. Is my NSTimer TRON's answer to
the Highlander, or is there something else going on?

No comments:

Post a Comment