Swift中如何取消延迟执行的pushViewController操作?
解决方案
你可以通过DispatchWorkItem来持有待执行的延迟任务,需要取消时直接调用其cancel()方法即可彻底终止任务执行,具体实现如下:
实现步骤
- 给当前控制器添加一个私有属性,用于存储第二页的待执行push任务
- 触发pushSecondVC时创建
DispatchWorkItem并存储,提交到主队列延迟执行 - 触发pushFirstVC或者页面即将消失时,调用存储任务的
cancel()方法并置空,终止待执行任务 - 执行任务前先判断任务是否已被取消,避免无效执行
完整代码示例
class TestViewController: UIViewController { // 存储第二页的待执行push任务 private var pushSecondTask: DispatchWorkItem? @IBAction func pushFirstVC() { // 先取消未执行的第二页push任务 pushSecondTask?.cancel() pushSecondTask = nil DispatchQueue.main.async { [weak self] in self?.navigationController?.pushViewController(FirstViewController(), animated: true) } } @IBAction func pushSecondVC() { // 先取消之前可能存在的旧任务,避免重复触发 pushSecondTask?.cancel() // 创建新的push任务 let task = DispatchWorkItem { [weak self] in // 执行前判断任务是否已被取消,已取消则直接返回 guard let self = self, !task.isCancelled else { return } self.navigationController?.pushViewController(SecondViewController(), animated: true) // 执行完成后清空任务 self.pushSecondTask = nil } pushSecondTask = task // 提交到主队列延迟执行 DispatchQueue.main.asyncAfter(deadline: .now() + 5.0, execute: task) } override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) // 页面即将消失时也取消所有待执行任务 pushSecondTask?.cancel() pushSecondTask = nil } }
补充说明
该方案可以覆盖所有需要取消的场景:
- 5秒内触发pushFirstVC时,第二页任务会被直接取消,不会执行push
- 5秒内用户pop离开当前页面,
viewWillDisappear会触发取消逻辑,即使之后再回到当前页面,任务也不会重新执行 - 重复触发pushSecondVC时,会自动取消之前的旧任务,仅保留最后一次触发的任务
内容的提问来源于stack exchange,提问作者Kelton
相关产品推荐
相关产品推荐

