我知道这些NSTimer
问题已经出现了无数次,但是由于似乎没有涉及执行更改UI的块的问题,因此我认为这仍然是一个原始问题。
我有一个UIButton
子类,为方便起见(我来自Android
背景),它具有onClick
和onHoldClick
函数。 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];
}
}
执行的块更改了float的值,该值用于更新标签的值,然后重绘标签。
第一次发生保留点击事件时,效果很好。在那之后,似乎计时器没有被取消,而新的计时器仍被添加。这是我的
cancelTimers
函数的样子(此处的调用是从与此主题相关的其他问题的集合中检索的):-(void)cancelTimers
{
[_timer invalidate];
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(death:) object:nil];
}
我在做什么错,该如何解决?
编辑
实际上,我确实已经具有响应修饰的功能:
- (void)clickUp:(id)sender
{
isClicked = NO;
[self cancelTimers];
_clickBlock();
}
此外,我已经意识到该问题来自未处理的取消事件。 iOS是否有理由自动取消我的长按?
最佳答案
解决了
由于该块重新绘制了UI,因此它还重新绘制了按钮(并重置了它们的功能)。此事件导致在按钮上调用了cancel事件-未处理。添加以下内容:
[self addTarget:self action:@selector(cancelClick:) forControlEvents:UIControlEventTouchCancel];
[self addTarget:self action:@selector(cancelClick:) forControlEvents:UIControlEventTouchUpOutside];
-(void)cancelClick:(id)sender
{
isClicked = NO;
[self cancelTimers];
}
除了重新考虑块中所做的更改外,我还克服了这个问题。
关于ios - 无法取消执行 block 的NSTimer,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16921204/