如何将导航控制器内presented视图的数据回传到自定义XIB视图
问题根因
你当前的代码存在两个核心错误:
- 层级获取逻辑错误:你弹出的是
ExtraOptionsNavigationController,该导航控制器的presentingViewController才是CreatePostModal实例,ExtraOptionsViewController作为导航控制器的子控制器,它的presentingViewController是外层的导航控制器,你之前的类型强转逻辑本身不成立。 - 之前使用代理方案失效的原因是你把代理赋值给了导航控制器,而非导航栈内的
ExtraOptionsViewController实例。
快速修复(直接修改现有代码)
调整donePressed方法内的层级获取逻辑即可:
@IBAction func donePressed(_ sender: Any) { // 先拿到当前控制器所在的导航容器 guard let navController = self.navigationController else { return } // 导航容器的presentingViewController才是CreatePostModal实例 guard let presenter = navController.presentingViewController as? CreatePostModal else { return } presenter.extraOptions = self.extraOptionsSelected print("赋值结果:\(presenter.extraOptions)") dismiss(animated: true, completion: nil) }
额外检查项:确认CreatePostModal的viewWillAppear/viewDidAppear等生命周期方法中没有重新把extraOptions赋值为空数组的逻辑。
更稳定的实现方案(闭包回调,无层级依赖)
这种跨页面传值更推荐用闭包回调,不会受页面层级变动影响:
- 首先在
ExtraOptionsViewController中定义回调属性:
class ExtraOptionsViewController: UIViewController { // 选中选项后的回调,参数为选中的数组 var onSelectComplete: (([String]) -> Void)? var extraOptionsSelected = [String]() @IBAction func donePressed(_ sender: Any) { // 直接触发回调传值,不需要关心外部层级 onSelectComplete?(extraOptionsSelected) dismiss(animated: true) } }
- 在
CreatePostModal弹出页面时设置回调:
@objc func addExtraOptions(_ sender: UITapGestureRecognizer? = nil) { let storyboard = UIStoryboard(name: "Main", bundle: nil) let navVC = storyboard.instantiateViewController(withIdentifier: "ExtraOptionsNavigationController") as! UINavigationController // 拿到导航栈内的ExtraOptionsViewController实例,设置回调 guard let extraVC = navVC.topViewController as? ExtraOptionsViewController else { return } extraVC.onSelectComplete = { [weak self] selected in self?.extraOptions = selected } navVC.modalPresentationStyle = .fullScreen present(navVC, animated: true) }
内容的提问来源于stack exchange,提问作者Vandal
相关产品推荐
相关产品推荐

