You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为模态推送转场添加条件,满足特定条件才允许返回上一控制器

解决方案:拦截导航返回与侧滑手势,阻止不符合条件的返回

这个需求完全可以实现!核心思路是拦截导航控制器的返回行为(包括系统返回按钮点击和侧滑返回手势),在触发返回前检查条件,不满足时弹出提示框。下面分两种常用场景给出具体实现:

一、自定义返回按钮(推荐,更灵活可控)

如果你的导航栏返回按钮是自定义的,直接给按钮添加点击事件,在事件里判断条件:

class SecondViewController: UIViewController {
    // 假设condition是你要判断的条件,比如表单是否填写完成
    var condition = false

    override func viewDidLoad() {
        super.viewDidLoad()
        
        // 自定义返回按钮
        let backButton = UIBarButtonItem(title: "返回", style: .plain, target: self, action: #selector(backButtonTapped))
        navigationItem.leftBarButtonItem = backButton
    }

    @objc private func backButtonTapped() {
        guard condition else {
            // 条件不满足,弹出提示
            let alert = UIAlertController(title: "提示", message: "You can't go back until [condition]", preferredStyle: .alert)
            alert.addAction(UIAlertAction(title: "确定", style: .default))
            present(alert, animated: true)
            return
        }
        // 条件满足,执行返回
        navigationController?.popViewController(animated: true)
    }
}

二、拦截系统返回按钮与侧滑手势

如果想保留系统默认的返回按钮样式,需要借助UINavigationControllerDelegate来拦截返回行为,同时处理侧滑手势:

1. 给当前导航控制器设置代理

在第二个视图控制器的viewWillAppear里设置代理,viewWillDisappear里移除(避免影响其他页面):

class SecondViewController: UIViewController, UINavigationControllerDelegate {
    var condition = false
    // 保存系统默认的侧滑手势代理
    private var originalInteractivePopGestureDelegate: UIGestureRecognizerDelegate?

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        navigationController?.delegate = self
        // 保存并禁用侧滑手势的默认代理,方便我们自己控制
        originalInteractivePopGestureDelegate = navigationController?.interactivePopGestureRecognizer?.delegate
        navigationController?.interactivePopGestureRecognizer?.delegate = self
    }

    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        navigationController?.delegate = nil
        // 恢复侧滑手势的默认代理
        navigationController?.interactivePopGestureRecognizer?.delegate = originalInteractivePopGestureDelegate
    }
}

2. 实现导航控制器代理方法,拦截返回

extension SecondViewController {
    func navigationController(_ navigationController: UINavigationController, shouldPop viewController: UIViewController) -> Bool {
        guard condition else {
            // 弹出提示
            let alert = UIAlertController(title: "提示", message: "You can't go back until [condition]", preferredStyle: .alert)
            alert.addAction(UIAlertAction(title: "确定", style: .default))
            present(alert, animated: true)
            
            // 这里返回false,阻止系统执行pop操作
            return false
        }
        return true
    }

    // 处理侧滑手势,条件不满足时禁用侧滑
    func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
        guard gestureRecognizer == navigationController?.interactivePopGestureRecognizer else {
            return true
        }
        return condition
    }
}

注意事项

  • 如果你用的是Objective-C,代码逻辑是一致的,只是语法上调整即可。
  • 确保condition的状态是实时更新的,比如用户完成操作后要把它设为true。
  • 第二种方式里,别忘了在页面消失时恢复导航控制器的代理和侧滑手势的代理,不然会影响其他页面的正常返回。

内容的提问来源于stack exchange,提问作者e2r3p13

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 04:04:30