我想在长任务运行时忽略按钮的所有触摸事件。
- (void)buttonAction{
NSLog(@"click!");
button.enabled = NO;
[self longTask];
}
- (void)longTask{
NSLog(@"task begin!");
sleep(5);
NSLog(@"task finished!");
button.enabled = YES;
}
在 longTask 期间,我再次单击按钮,它真的没有任何反应。但是,当 longTask 完成后,它会自动响应点击事件并再次执行 longTask!
当按钮的启用值为'NO'时,我点击了多少次,longTask将执行多少次。
2013-08-20 09:24:49.478 AppName[2518:c07] click!
2013-08-20 09:24:49.479 AppName[2518:c07] task begin!
2013-08-20 09:24:54.481 AppName[2518:c07] task finished!
2013-08-20 09:24:54.482 AppName[2518:c07] click!
2013-08-20 09:24:54.482 AppName[2518:c07] task begin!
2013-08-20 09:24:59.484 AppName[2518:c07] task finished!
我尝试设置 userInteractionEnabled=NO 但得到了相同的结果。
当一个长任务正在运行并且从不执行任务时,如何让它忽略所有触摸事件?换句话说,只有在单击按钮时才执行longTask,它的启用值为'YES'?
感谢任何帮助!
Best Answer-推荐答案 strong>
sleep 只是卡住了负责所有 UI 交互的主线程。
您应该在后台执行所有长时间的任务,这可以通过 GCD 轻松完成.只需像下面那样做,你应该能够实现你想要的:
- (void)buttonAction{
NSLog(@"click!");
button.enabled = NO;
dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void){
//Background Thread
[self longTask];
dispatch_async(dispatch_get_main_queue(), ^(void){
button.enabled = YES;
});
});
}
- (void)longTask{
NSLog(@"task begin!");
[NSThread sleepForTimeInterval:5];
NSLog(@"task finished!");
}
请注意,当您这样做时,您的所有 UI 都不会再被阻止,只会禁用所需的按钮。
正如@Erik Godard 所提到的,您确实应该考虑在执行此类任务时使用某种 UI 反馈。您可以在将按钮的启用属性设置为 NO 的同一区域启动一些进程指示器,并在将属性设置为 YES 时停止它
另一种不使用 GCD 的方法是通过 NSRunLoop 的方法 runUntilDate 更改 sleep 。这样你的主线程也不会被阻塞,你就可以实现你想要的。
- (void)buttonAction{
NSLog(@"click!");
self.addCartButton.enabled = NO;
[self longTask];
}
- (void)longTask{
NSLog(@"task begin!");
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:5]];
NSLog(@"task finished!");
self.addCartButton.enabled = YES;
}
这两种方法都经过测试,似乎都有效。
关于ios - 在较长的任务时间内忽略UIButton的触摸事件,我们在Stack Overflow上找到一个类似的问题:
https://stackoverflow.com/questions/18325602/
|