2013-06-04 26 views
1

我知道這些NSTimer問題已經出現了很多次,但是由於沒有涉及執行更改UI的塊,我認爲這仍然是一個原始問題。無法取消執行塊的NSTimer

我有UIButton一個子類,爲方便起見(我,從Android背景的),有一個onClickonHoldClick功能。 onClick只需要一個塊並在響應UIControlEventTouchUpInside的選擇器中執行該塊。點擊功能很好。例如:

[myButton setOnClick:^{ 
    NSLog(@"clicked"); 
}]; 

保持點擊功能不能很好地工作。

[myButton setOnHoldClick:^{ 
    NSLog(@"still holding click..."); 
}]; 

這偵聽UIControlEventTouchDown事件,並且在延遲之後執行任務:

- (void)clickDown:(id)sender 
{ 
    isClicked = YES; 

    [self performSelector:@selector(holdLoop:) withObject:nil afterDelay:delay];//For the sake of the example, delay is set to 0.5 
} 

的保持環運行在另一功能的重複計時器,它處理塊執行(計時器變量是在頭文件中聲明的NSTimer):

-(void)holdLoop:(id)sender 
{ 
    [self cancelTimers]; 
    _timer = [NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(death:) userInfo:nil repeats:YES]; 
} 

-(void)death:(id)_delay 
{ 

    if (isClicked) 
    { 
     _holdBlock(); 
    } 
    else 
    { 
     [self cancelTimers]; 

    } 
} 

執行茶的塊更新浮點值,用於更新標籤的值,然後重新繪製標籤的值。

第一次發生保持點擊事件時,這很有效。之後,似乎定時器不會被取消,新的定時器仍然被添加。這是我cancelTimers功能是什麼樣子(這裏的呼叫從的其他問題收集關於這個主題檢索):

-(void)cancelTimers 
{ 
    [_timer invalidate]; 
    [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(death:) object:nil]; 
} 

我在做什麼錯了,我該如何解決?

編輯

我這樣做,其實已經有響應裏面潤色功能:

- (void)clickUp:(id)sender 
{ 
    isClicked = NO; 
    [self cancelTimers]; 
    _clickBlock(); 
} 

而且,我已經意識到這個問題來自未處理的取消事件。 iOS會自動取消我的長按是否有原因?

+0

你想讓計時器只觸發一次嗎?或者只有在按鈕被按下時纔開火? –

+0

@ MohannadA.Hassan,我只希望它在按下按鈕時觸發。 'isClicked' BOOL值用於跟蹤點擊狀態。 – Phil

+0

所以你確定'isClicked'應該設置爲'NO'。 –

回答

1

當我從註釋和代碼理解的,clickDown:被調用UIControlEventTouchDown所以當第一次觸摸該按鈕向下isClicked設置爲YES。您需要爲事件UIControlEventTouchUpInside添加選擇器。當用戶在按鈕的邊界上舉起手指時調用它。在該方法中,將isClicked設置爲NO

+0

我確實有這個事件已經註冊。請參閱編輯我的問題。 – Phil

2

解決

由於塊的重新繪製UI,也有人重繪按鈕(和復位它們的功能)。此事件導致在按鈕上調用取消事件 - 未處理該事件。添加以下內容:

[self addTarget:self action:@selector(cancelClick:) forControlEvents:UIControlEventTouchCancel]; 
[self addTarget:self action:@selector(cancelClick:) forControlEvents:UIControlEventTouchUpOutside]; 


-(void)cancelClick:(id)sender 
{ 
    isClicked = NO; 
    [self cancelTimers]; 
} 

除了重新考慮塊中做了哪些更改,也讓我超越了這個問題。