Swift:如何取消延迟的 pushViewController?

Posted

技术标签:

【中文标题】Swift:如何取消延迟的 pushViewController?【英文标题】:Swift: How to cancel a delayed pushViewController? 【发布时间】:2021-12-20 09:42:04 【问题描述】:

我有这种情况,我可以从给定的视图控制器推送两个不同的视图控制器,第一个将立即推送,第二个在 API 调用之后推送,所以为了模仿它,我写了这个:

class TestViewController: UIViewController 
    @IBAction func pushFirstVC() 
        DispatchQueue.main.async  [weak self] in
            weakSelf?.navigationController?.pushViewController(FirstViewController(), animated: true)
        
    
    
    @IBAction func pushSecondVC() 
        DispatchQueue.main.asyncAfter(deadline: .now() + 5.0)  [weak self] in
            self?.navigationController?.pushViewController(SecondViewController(), animated: true)
        
    

现在假设用户首先触发了pushSecondVC() 事件,然后在接下来的 5 秒内触发了pushFirstVC() - 然后我肯定会取消最初的pushSecondVC(),以免推送@ 987654325@ 实例,即使用户在这 5 秒延迟内弹回TestViewController

我尝试了几件事,例如在viewDidAppear 中添加一个canPush 标志,在viewDidAppearfalse 中添加false。但是,如果用户在 5 秒延迟内返回TestViewController,这并不能阻止推送视图控制器的发生。所以我想做的是专门取消预期的任务,但我不知道该怎么做。

感谢您的帮助

【问题讨论】:

【参考方案1】:

Grand Central Dispatch 不提供在阻塞排队后取消阻塞的方法。有一个类似的机制,NSOperation,它确实提供了一种取消挂起操作的方法。不幸的是,我手头没有任何源代码。

但比这更简单的可能是添加一个“取消”标志并检查您是否在弹出发生之前取消了某些内容。

class TestViewController: UIViewController 
    var secondPushCancelled = false

    @IBAction func pushFirstVC() 
        DispatchQueue.main.async  [weak self] in
            self?.secondPushCancelled = false
            weakSelf?.navigationController?.pushViewController(FirstViewController(), animated: true)
        
    

    @IBAction func pushSecondVC() 
        DispatchQueue.main.asyncAfter(deadline: .now() + 5.0)  [weak self] in
            if (self != nil) && !self!.secondPushCancelled 
                self?.navigationController?.pushViewController(SecondViewController(), animated: true)
            
        
    

    func cancelSecondPush() 
        secondPushCancelled = true
    

最后,如果你看一下 Swift 结构化并发,就会发现异步任务树的概念。使用树,如果您取消拥有子任务的任务,则子任务可以确定它们是否已被取消并跳过不再需要的工作。

欲了解更多信息,请关注Explore structured concurrency in Swift

【讨论】:

以上是关于Swift:如何取消延迟的 pushViewController?的主要内容,如果未能解决你的问题,请参考以下文章

在 Swift 中有效地取消关键帧动画

如何取消延迟的线程?

如何在 Rails 中使用延迟作业取消预定作业?

Swift:如何无延迟地刷新 tableview (UIRefreshControl)

swift延迟后如何更新UI

NSTimer - 如何在 Swift 中延迟