我正在显示一个UIView,用于显示用户为其他目的标记的地图功能的信息,例如删除或编辑。标记功能时,我显示的是包含信息和撤消选项的UIView。在一段固定的时间内显示UIView已经完成并正常工作,但是,我希望延迟有一个滑动到期,也就是说,如果用户选择另一个地图要素进行标记,延迟应该自行重置并且UIView应该在指定的全部时间内保持可见。我正在寻找的是滑动过期。到目前为止我的代码:
double delaySeconds = 15;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delaySeconds * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[self toggleUndoViewToShow:NO];
});
所以,我的延迟时间是15秒,如果在这15秒内标记了另一个功能,我希望视图在整个延迟时间内保持可见状态。我怎么能这样做?谢谢!
答案 0 :(得分:3)
使用计时器调度源。使用dispatch_source_create()
创建它,并将DISPATCH_SOURCE_TYPE_TIMER
作为类型传递。致电dispatch_source_set_timer()
设置开始时间。要模拟仅运行其任务一次的dispatch_after()
,请使用DISPATCH_TIME_FOREVER
作为间隔。调用dispatch_source_set_event_handler()
将任务设置为在指定时间到达时执行。此外,任务需要使用dispatch_source_cancel()
取消源以清理源。在源上调用dispatch_resume()
以允许它(它在暂停状态下创建)。
您可以随时使用dispatch_source_set_timer()
来调整任务运行的时间。您也可以随时取消它。
由于这比dispatch_after()
稍微复杂一些,您可以将其包装在帮助器中以便为您设置。辅助函数的调用者将提交一个不知道取消源的需要的任务块。您的助手会将其包装在调用提供的块的任务中,然后执行dispatch_source_cancel()
。
对于您需要的非常简单的情况,上述情况可能有点过分。你也可以这样做:
__block int savedTaskID;
if ([NSThread isMainThread])
savedTaskID = ++self.currentTaskID; // an integer property on your view
else dispatch_sync(dispatch_get_main_queue(), ^{
savedTaskID = ++self.currentTaskID;
});
double delaySeconds = 15;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delaySeconds * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
if (savedTaskID == self.currentTaskID)
[self toggleUndoViewToShow:NO];
});
如果您想延迟切换,只需重复上述步骤即可。由于增加currentTaskID
,当先前提交的任务运行时,它们什么都不做。这有点浪费,因为绝对的任务仍然存在并最终运行,但听起来不会发生太多。
答案 1 :(得分:1)
根据我的理解,您需要取消计划在某个延迟后执行的现有块,并以15秒的新延迟安排等效块。 This应该可以帮助您取消计划运行的延迟块。