Swift iOS:手动跳转页面时prepare方法失效致数据传递失败
解决手动实例化视图控制器时数据无法传递的问题
这完全是正常现象哦,因为prepare(for:sender:)方法只在通过Storyboard Segue触发跳转时才会被系统自动调用——你手动用instantiateViewController创建视图控制器实例的话,系统根本不会触发这个方法,自然就没法通过它完成数据传递啦。
给你两种常用的解决方案,按需选择就行:
方案一:直接给目标视图控制器的属性赋值
这是最直接的方式,当你手动实例化出目标VC后,直接把要传递的数据赋值给它的公开属性:
// 手动实例化目标视图控制器(记得替换成你的VC标识符和类名) if let targetVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "YourTargetVCID") as? YourTargetViewController { // 直接给目标VC的属性赋值(前提是TargetVC里已定义对应公开属性) targetVC.passedString = "要传递的文本内容" targetVC.currentUserModel = yourUserModel // 执行跳转(根据需求选push或present) navigationController?.pushViewController(targetVC, animated: true) // 或者 present(targetVC, animated: true, completion: nil) }
注意:要确保目标视图控制器里的属性是public或者默认的内部访问级别(同一模块下可直接访问),别写成私有属性哦。
方案二:封装自定义初始化方法(推荐)
如果要传递的数据较多,或者想让数据传递更规范,可以给目标视图控制器写一个自定义初始化方法,强制调用者传入必要数据:
先在目标视图控制器中定义:
class YourTargetViewController: UIViewController { // 定义需要接收的属性 let requiredUserData: UserModel let optionalNote: String? // 自定义初始化方法 init(userData: UserModel, note: String?) { self.requiredUserData = userData self.optionalNote = note super.init(nibName: nil, bundle: nil) } // 必须实现这个初始化方法(Storyboard实例化的要求) required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } override func viewDidLoad() { super.viewDidLoad() // 后续就可以直接使用这些数据了 print("接收的用户数据:\(requiredUserData.name)") } }
然后跳转时这样用:
// 用自定义初始化方法创建实例 let targetVC = YourTargetViewController(userData: currentUser, note: "来自手动跳转的备注") // 执行跳转 navigationController?.pushViewController(targetVC, animated: true)
这种方式的好处是,调用者必须传入必要数据,避免出现数据为空的意外,代码可读性和健壮性更高。
额外小技巧:复用数据传递逻辑
如果你既想用Storyboard Segue又想支持手动跳转,可以把数据传递的逻辑抽成单独方法,两种跳转方式复用:
// 抽离数据传递逻辑 private func setupTargetVC(_ vc: YourTargetViewController) { vc.passedString = "要传递的内容" vc.currentUserModel = yourUserModel } // Segue跳转时调用 override func prepare(for segue: UIStoryboardSegue, sender: Any?) { if let targetVC = segue.destination as? YourTargetViewController { setupTargetVC(targetVC) } } // 手动跳转时调用 func triggerManualJump() { if let targetVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "YourTargetVCID") as? YourTargetViewController { setupTargetVC(targetVC) navigationController?.pushViewController(targetVC, animated: true) } }
这样不管哪种跳转方式,都用同一个方法处理数据传递,避免重复代码~
内容的提问来源于stack exchange,提问作者user9683424
相关产品推荐
相关产品推荐

