2013-08-18 155 views
0

我試圖在媒體播放器中設置一個「FastForward/Next」按鈕,可以輕觸移動到下一首歌曲或在當前歌曲中保持快進。大多數情況下,它的工作原理是:你可以成功地快速前進,併成功移動到下一首歌曲,但事實是,使它工作的NSTimer從不會失效,所以一旦開始快速前進,就永遠不會停止。UIGestureRecognizer與NSTimer不會死亡

我設置的手勢識別在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]; 

,這裏是函數的肉:

- (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]; 
} 

這裏是棘手的部分:當我在if(_holdFastForward.state == 0)行設置斷點,只要我放開按鈕(它應該)就開始工作,併成功調用endFastForward方法。據我的估計,這應該殺死計時器並結束整個週期,但隨後再次調用executeFastForward,然後再一次。 invalidate行似乎什麼都不做(並且我的代碼中沒有其他要點叫executeFastForward)。

任何想法?這看起來很簡單,如果invalidate一行工作,一切都將是完美的。我只是不知道爲什麼executeFastForward繼續被稱爲。是我的NSTimer TRON對Highlander的答案,還是還有其他事情正在進行?

回答

0

好,經過大量的實驗(並受到this answer中的if聲明的啓發而成爲一個不相關但相似的問題),我終於找到了一個解決方案:不要檢查executeFastForward方法中手勢的結尾,而是startFastForward方法。此外,原來startFastForward方法被反覆調用,重新創建計時器,因此if語句也通過將計時器限制爲UIGestureRecognizerStateBegan來停止該方法。

這裏是工作的代碼,誰想要它:

- (IBAction)startFastForward:(UIGestureRecognizer *)gestureRecognizer { 
    if(gestureRecognizer.state == UIGestureRecognizerStateBegan) { 
     _timerFastForward = [NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(executeFastForward) userInfo:nil repeats:YES]; 
    } else if(gestureRecognizer.state == UIGestureRecognizerStateEnded) { 
     [self endFastForward:self]; 
    } 
} 

- (void)executeFastForward { 
    [_avPlayer seekToTime:CMTimeMake(CMTimeGetSeconds([_avPlayer currentTime]) + 10, 1)]; 
} 

- (IBAction)endFastForward:(id)sender { 
    [_timerFastForward invalidate]; 
    _timerFastForward = nil; 
} 
0

NSTimer需要選擇應該取一個參數爲NSTimer *,這裏是從蘋果公司的documentation

選擇器的引用必須對應於返回void並接受一個參數的方法。計時器將自身作爲參數傳遞給此方法。

試圖改變自己的executeFastForward方法的簽名是這樣的:

-(void) executeFastForward:(NSTimer *)timer 

比你能無效作爲參數傳遞的計時器,它實際上是燒製的計時器對象

+0

沒有幫助。 :/但我確實得到了一個線索:在連接remoteControlReceivedWithEvent(使用相同的NSTimer方法完美工作)之後,我可以放心地說,它與啓動整個事件的'UIGestureRecognizer'有關。任何想法爲什麼會搞亂'invalidate'方法? – Nerrolken