如何不使用通知实现ViewController-B向ViewController-A返回结果?
无需通知实现ViewController间的结果回传方案
当然可以不用通知!通知其实更适合跨组件的全局消息传递,这种两个页面之间的直接结果回传,用代理模式或者**闭包(Block)**会更直接、耦合度更低,完全是iOS开发里的标准操作。下面给你详细拆解两种实现方式:
方法一:代理模式(Delegate Pattern)
这是iOS开发中最经典的回调方案,代码结构清晰,适合复杂的交互场景:
- 在ViewController-B中定义代理协议
// ViewController-B.swift import UIKit // 定义代理协议,规定回传方法 protocol ViewControllerBDelegate: AnyObject { func viewControllerB(_ vc: ViewControllerB, didFinishWithResult result: String) } class ViewControllerB: UIViewController { // 定义弱引用的代理属性,避免循环引用 weak var delegate: ViewControllerBDelegate? // 假设这是关闭页面的按钮点击事件 @IBAction func closeButtonTapped(_ sender: UIButton) { // 调用代理方法传递结果 delegate?.viewControllerB(self, didFinishWithResult: "Some Value (Result)") // 关闭当前页面 dismiss(animated: true) } }
- 在ViewController-A中遵守协议并设置代理
// ViewController-A.swift import UIKit class ViewControllerA: UIViewController, ViewControllerBDelegate { // 打开ViewController-B的按钮点击事件 @IBAction func openViewControllerBTapped(_ sender: UIButton) { let vcB = ViewControllerB() // 设置代理为当前ViewController-A vcB.delegate = self present(vcB, animated: true) } // 实现代理方法,接收并处理返回的结果 func viewControllerB(_ vc: ViewControllerB, didFinishWithResult result: String) { print("收到ViewController-B返回的结果:\(result)") // 这里可以根据需求更新UI、存储数据等 } }
方法二:闭包(Closure/Block)
这种方式代码更紧凑简洁,适合简单的结果回传场景:
- 在ViewController-B中定义闭包属性
// ViewController-B.swift import UIKit class ViewControllerB: UIViewController { // 定义结果回调闭包,可选类型避免空调用 var onResult: ((String) -> Void)? @IBAction func closeButtonTapped(_ sender: UIButton) { // 调用闭包传递结果 onResult?("Some Value (Result)") dismiss(animated: true) } }
- 在ViewController-A中设置闭包回调
// ViewController-A.swift import UIKit class ViewControllerA: UIViewController { @IBAction func openViewControllerBTapped(_ sender: UIButton) { let vcB = ViewControllerB() // 设置闭包,注意用[weak self]避免循环引用 vcB.onResult = { [weak self] result in guard let self = self else { return } print("收到ViewController-B返回的结果:\(result)") // 处理结果逻辑,比如更新页面显示 } present(vcB, animated: true) } }
补充说明
不管你是用present弹出ViewController-B,还是通过导航控制器push进入,这两种方案的回传逻辑都是通用的,只需要把关闭页面的代码换成对应的dismiss(animated:)或popViewController(animated:)即可。
内容的提问来源于stack exchange,提问作者Bhaumik Surani
相关产品推荐
相关产品推荐

