我正在尝试让我的应用程序在延迟后执行操作,但是必须在用户与UIScrollView
进行交互/滚动时完成。
我不确定为什么performSelector:withObject:afterDelay
或scheduledTimerWithTimeInterval:target:selector:userInfo:repeats:
都不会触发。是因为他们是在后台线程吗?
有任何建议或帮助吗?
答案 0 :(得分:24)
默认情况下,NSTimer
和performSelector:withObject:afterDelay:
都只在正常运行循环模式下触发。滚动时,运行循环处于事件跟踪模式。
您必须在所有常见模式下安排定时动作:
NSTimer *timer = [NSTimer timerWithTimeInterval:0.016 target:self selector:@selector(fire:) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
或
[self performSelector:@selector(fire:) withObject:nil afterDelay:1.0 inModes:[NSArray arrayWithObject:NSRunLoopCommonModes]];
还有专门的NSEventTrackingRunLoopMode
。
答案 1 :(得分:4)
确保延迟触发发生在NSRunLoopCommonModes
上。默认设置为NSDefaultRunLoopMode
,在此期间不会收到消息滚动。
[self performSelector:@selector(fire:) withObject:nil afterDelay:2.0 inModes:@[NSRunLoopCommonModes]];
或者你也可以使用同样方式的GCD
(不确定它使用哪种runloop模式)
double delayInSeconds = 2.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
<#code to be executed on the main queue after delay#>
});
答案 2 :(得分:0)
对于Swift:
performSelector(#selector(fire:), withObject: sender, afterDelay: 1.0, inModes: [NSRunLoopCommonModes])