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

iOS中present的ViewController dismissed时如何通知父ViewController

解决方案

方案1:使用闭包回调(最推荐,耦合度最低)

  • 适用场景:单个选择结果回传,逻辑清晰无通知全局广播的冗余
  • 实现步骤:
    1. 在被present的ViewController中定义回调闭包
    // 被present的VC代码
    var selectCompletion: ((_ selectedOption: Int) -> Void)?
    
    1. 用户触发选择操作、dismiss之前调用闭包
    // 用户选择后执行
    selectCompletion?(1) // 传入你需要回传的参数
    self.dismiss(animated: true)
    
    1. 父VC在present的时候给闭包赋值
    // 父VC present时的代码
    let presentedVC = PresentedViewController()
    presentedVC.selectCompletion = { [weak self] selectedOption in
        guard let self = self else { return }
        // 这里处理选择结果,不需要等viewWillAppear触发
        self.handleSelectedOption(option: selectedOption)
    }
    self.present(presentedVC, animated: true)
    

方案2:使用系统通知中心(NotificationCenter,适合多对象同时监听选择结果的场景)

  • 注意不要在dismiss之后才发通知,要在dismiss之前发送,确保父VC已经注册监听就能收到
  • 实现步骤:
    1. 父VC在viewDidLoad中注册通知监听
    // 父VC代码
    override func viewDidLoad() {
        super.viewDidLoad()
        NotificationCenter.default.addObserver(self, selector: #selector(handleSelectNotification(notify:)), name: NSNotification.Name("UserSelectedOptionNotification"), object: nil)
    }
    
    1. 实现通知处理方法
    @objc private func handleSelectNotification(notify: Notification) {
        guard let option = notify.userInfo?["selectedOption"] as? Int else { return }
        // 处理选择结果
    }
    
    1. 被present的VC用户选择后先发通知再dismiss
    // 被present的VC代码
    NotificationCenter.default.post(name: NSNotification.Name("UserSelectedOptionNotification"), object: nil, userInfo: ["selectedOption": 1])
    self.dismiss(animated: true)
    
    1. 父VC销毁时移除通知监听
    deinit {
        NotificationCenter.default.removeObserver(self)
    }
    

方案3:使用代理模式

  • 适用场景:回传逻辑复杂,多个回调方法的场景
  • 实现步骤:
    1. 定义代理协议
    protocol SelectViewControllerDelegate: AnyObject {
        func didSelectOption(option: Int)
    }
    
    1. 被present的VC中定义代理属性
    weak var delegate: SelectViewControllerDelegate?
    
    1. 用户选择后调用代理方法再dismiss
    delegate?.didSelectOption(option: 1)
    self.dismiss(animated: true)
    
    1. 父VC遵循代理协议,present时设置代理
    // 父VC遵循协议
    extension ParentViewController: SelectViewControllerDelegate {
        func didSelectOption(option: Int) {
            // 处理选择结果
        }
    }
    // present时代码
    let presentedVC = PresentedViewController()
    presentedVC.delegate = self
    self.present(presentedVC, animated: true)
    

补充说明:为什么viewWillAppear没触发?iOS 13之后如果present的是pageSheet样式(非全屏)的VC,dismiss的时候父VC的viewWillAppear不会触发,如果要强制触发可以在present的时候设置presentedVC.modalPresentationStyle = .fullScreen,但这种方案会修改原有交互样式,不推荐优先使用。

内容的提问来源于stack exchange,提问作者D C T

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 02:00:03