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
标志,在viewDidAppear
和false
中添加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?的主要内容,如果未能解决你的问题,请参考以下文章