iOS中present的ViewController dismissed时如何通知父ViewController
解决方案
方案1:使用闭包回调(最推荐,耦合度最低)
- 适用场景:单个选择结果回传,逻辑清晰无通知全局广播的冗余
- 实现步骤:
- 在被present的ViewController中定义回调闭包
// 被present的VC代码 var selectCompletion: ((_ selectedOption: Int) -> Void)?- 用户触发选择操作、dismiss之前调用闭包
// 用户选择后执行 selectCompletion?(1) // 传入你需要回传的参数 self.dismiss(animated: true)- 父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已经注册监听就能收到
- 实现步骤:
- 父VC在viewDidLoad中注册通知监听
// 父VC代码 override func viewDidLoad() { super.viewDidLoad() NotificationCenter.default.addObserver(self, selector: #selector(handleSelectNotification(notify:)), name: NSNotification.Name("UserSelectedOptionNotification"), object: nil) }- 实现通知处理方法
@objc private func handleSelectNotification(notify: Notification) { guard let option = notify.userInfo?["selectedOption"] as? Int else { return } // 处理选择结果 }- 被present的VC用户选择后先发通知再dismiss
// 被present的VC代码 NotificationCenter.default.post(name: NSNotification.Name("UserSelectedOptionNotification"), object: nil, userInfo: ["selectedOption": 1]) self.dismiss(animated: true)- 父VC销毁时移除通知监听
deinit { NotificationCenter.default.removeObserver(self) }
方案3:使用代理模式
- 适用场景:回传逻辑复杂,多个回调方法的场景
- 实现步骤:
- 定义代理协议
protocol SelectViewControllerDelegate: AnyObject { func didSelectOption(option: Int) }- 被present的VC中定义代理属性
weak var delegate: SelectViewControllerDelegate?- 用户选择后调用代理方法再dismiss
delegate?.didSelectOption(option: 1) self.dismiss(animated: true)- 父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
相关产品推荐
相关产品推荐

