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:代理模式
- 在ViewControllerB里定义一个代理协议:
protocol ViewControllerBDelegate: AnyObject { // 可以根据需求添加参数,比如要传数据就加个data参数 func didTapAccept(in vc: ViewControllerB, with data: String?) } - 在ViewControllerB里添加代理属性:
weak var delegate: ViewControllerBDelegate? // 假设你要传的数据是这个 var resultData: String? - 在ViewControllerA的
prepare(for:sender:)方法里设置代理:override func prepare(for segue: UIStoryboardSegue, sender: Any?) { if let vcB = segue.destination as? ViewControllerB { vcB.delegate = self } } - 让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) } } - 弹窗「Accept」按钮的点击事件里调用代理方法:
@IBAction func acceptButtonTapped(_ sender: UIButton) { // 先关闭弹窗 dismiss(animated: true) { [weak self] in // 调用代理方法,传数据 self?.delegate?.didTapAccept(in: self!, with: self?.resultData) } }
方法2:闭包回调(更简洁)
- 在ViewControllerB里添加一个闭包属性:
var onAccept: ((String?) -> Void)? // 泛型参数可以根据你要传的数据类型改 var resultData: String? - 在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) } } } - 弹窗「Accept」按钮的点击事件里触发闭包:
@IBAction func acceptButtonTapped(_ sender: UIButton) { dismiss(animated: true) { [weak self] in self?.onAccept?(self?.resultData) } }
小提醒: 不管用哪种方法,都记得用[weak self]避免循环引用,防止内存泄漏哦~
内容的提问来源于stack exchange,提问作者MathEnthusiast
相关产品推荐
相关产品推荐

