无法取消执行块的ntimer



我知道这些NSTimer问题已经出现了很多次,但是由于似乎没有涉及到执行改变UI的块,我认为这仍然是一个原始问题。

我有一个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];
    }
}

执行块修改浮点数的值,该浮点数用于更新标签的值,然后重新绘制标签的值。

第一次hold click事件发生时,这种方法非常有效。在那之后,计时器似乎不会被取消,新的计时器仍然会被添加。这是我的cancelTimers函数的样子(这里的调用是从关于这个主题的其他问题的集合中检索的):

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

我做错了什么,我如何修复它?

编辑

事实上,我已经有了响应触摸的函数:

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

此外,我已经意识到这个问题来自一个未处理的取消事件。iOS会自动取消我的长按吗?

已解决

由于块重绘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];
}

以及重新考虑在块中所做的更改,使我度过了这个问题。

正如我从注释和代码中理解的那样,clickDown:是为UIControlEventTouchDown调用的,所以当按钮第一次被触摸时,isClicked被设置为YES。您需要向事件UIControlEventTouchUpInside添加一个选择器。当用户在按钮的边界内抬起手指时,它就会被调用。在该方法中,设置isClickedNO

最新更新