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

iOS开发:点击弹窗Accept后从UIViewController B返回至A的实现

嘿,针对你这个需求,我给你整理了几个实用的方案,分基础场景和需要传数据的进阶场景,你可以根据自己的Segue跳转类型来选:

基础方案:直接返回(无需传数据)

首先得先确认你从A到B的Segue是哪种跳转类型:

  • 如果是Modal跳转(也就是B是被present出来的,Storyboard里Segue的Presentation设置为Full Screen/Page Sheet等):
    在B里给弹窗的「Accept」按钮绑定点击事件,然后在事件方法里先关闭弹窗,再dismiss当前的B控制器:

    @IBAction func acceptButtonTapped(_ sender: UIButton) {
        // 先关闭弹窗
        self.dismiss(animated: true) { [weak self] in
            // 再返回A
            self?.dismiss(animated: true, completion: nil)
        }
    }
    

    注意: 这里用嵌套的dismiss是因为弹窗本身也是一个modal控制器,所以先关弹窗,再关B。

  • 如果是Push跳转(A在UINavigationController栈里,Segue类型是Show):
    同样给「Accept」按钮绑定点击事件,先关弹窗,再从导航栈pop回A:

    @IBAction func acceptButtonTapped(_ sender: UIButton) {
        // 先关闭弹窗
        dismiss(animated: true) { [weak self] in
            // 返回A
            self?.navigationController?.popViewController(animated: true)
        }
    }
    
进阶方案:需要把B的数据传回A时

如果点击「Accept」后还要把B里的一些数据带给A,那用代理或者闭包会更规范:

方法1:代理模式

  1. 在ViewControllerB里定义一个代理协议:
    protocol ViewControllerBDelegate: AnyObject {
        // 可以根据需求添加参数,比如要传数据就加个data参数
        func didTapAccept(in vc: ViewControllerB, with data: String?)
    }
    
  2. 在ViewControllerB里添加代理属性:
    weak var delegate: ViewControllerBDelegate?
    // 假设你要传的数据是这个
    var resultData: String?
    
  3. 在ViewControllerA的prepare(for:sender:)方法里设置代理:
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if let vcB = segue.destination as? ViewControllerB {
            vcB.delegate = self
        }
    }
    
  4. 让ViewControllerA遵守并实现代理方法:
    extension ViewControllerA: ViewControllerBDelegate {
        func didTapAccept(in vc: ViewControllerB, with data: String?) {
            // 这里可以处理传回的数据,比如更新A的UI
            if let data = data {
                print("收到B传回的数据:\(data)")
            }
            // 然后返回A,根据跳转类型选pop或dismiss
            navigationController?.popViewController(animated: true)
            // 或者 dismiss(animated: true, completion: nil)
        }
    }
    
  5. 弹窗「Accept」按钮的点击事件里调用代理方法:
    @IBAction func acceptButtonTapped(_ sender: UIButton) {
        // 先关闭弹窗
        dismiss(animated: true) { [weak self] in
            // 调用代理方法,传数据
            self?.delegate?.didTapAccept(in: self!, with: self?.resultData)
        }
    }
    

方法2:闭包回调(更简洁)

  1. 在ViewControllerB里添加一个闭包属性:
    var onAccept: ((String?) -> Void)? // 泛型参数可以根据你要传的数据类型改
    var resultData: String?
    
  2. 在ViewControllerA的prepare(for:sender:)里设置闭包:
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if let vcB = segue.destination as? ViewControllerB {
            vcB.onAccept = { [weak self] data in
                // 处理传回的数据
                if let data = data {
                    print("收到B传回的数据:\(data)")
                }
                // 返回A
                self?.navigationController?.popViewController(animated: true)
                // 或者 self?.dismiss(animated: true, completion: nil)
            }
        }
    }
    
  3. 弹窗「Accept」按钮的点击事件里触发闭包:
    @IBAction func acceptButtonTapped(_ sender: UIButton) {
        dismiss(animated: true) { [weak self] in
            self?.onAccept?(self?.resultData)
        }
    }
    

小提醒: 不管用哪种方法,都记得用[weak self]避免循环引用,防止内存泄漏哦~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 04:30:05