Swift中如何从第二个ViewController调用第一个ViewController的函数?
问题分析与解决方案
你当前的错误核心在于:你创建了一个全新的FirstViewController实例,而不是当前已经存在、正在展示的那个实例。调用这个新实例的c_count()只会修改它内部的c值,对原页面毫无作用,而且这个未被正确持有/展示的实例可能触发调试断点。
以下是几种可行的实现方式:
方案1:闭包(Closure)(轻量首选)
在第二个页面定义闭包属性,跳转时把第一个页面的方法传递进去。
修改FirstViewController(添加跳转逻辑)
class FirstViewController: UIViewController { var c = 0 override func viewDidLoad() { super.viewDidLoad() } func c_count() { c += 1 print("当前c的值:\(c)") } // 跳转到SecondViewController的示例代码 @IBAction func goToSecondVC(_ sender: Any) { guard let secondVC = storyboard?.instantiateViewController(withIdentifier: "SecondViewController") as? SecondViewController else { return } // 传递闭包,捕获当前实例的c_count方法 secondVC.updateCountAction = { [weak self] in self?.c_count() } navigationController?.pushViewController(secondVC, animated: true) } }
修改SecondViewController
class SecondViewController: UIViewController { // 定义闭包属性 var updateCountAction: (() -> Void)? override func viewDidLoad() { super.viewDidLoad() } @IBAction func button(_ sender: Any) { // 调用闭包,触发第一个页面的方法 updateCountAction?() } }
方案2:代理模式(适合复杂交互)
通过定义协议,让第一个页面成为第二个页面的代理。
定义代理协议
protocol SecondVCDelegate: AnyObject { func needUpdateCount() }
修改SecondViewController
class SecondViewController: UIViewController { // 代理属性必须用weak修饰,避免循环引用 weak var delegate: SecondVCDelegate? override func viewDidLoad() { super.viewDidLoad() } @IBAction func button(_ sender: Any) { delegate?.needUpdateCount() } }
修改FirstViewController
class FirstViewController: UIViewController, SecondVCDelegate { var c = 0 override func viewDidLoad() { super.viewDidLoad() } func c_count() { c += 1 print("当前c的值:\(c)") } // 实现代理方法 func needUpdateCount() { c_count() } // 跳转逻辑 @IBAction func goToSecondVC(_ sender: Any) { guard let secondVC = storyboard?.instantiateViewController(withIdentifier: "SecondViewController") as? SecondViewController else { return } secondVC.delegate = self navigationController?.pushViewController(secondVC, animated: true) } }
方案3:通知中心(适合跨多层页面交互)
通过系统通知机制传递事件,耦合度稍高,适合复杂场景。
修改FirstViewController
class FirstViewController: UIViewController { var c = 0 override func viewDidLoad() { super.viewDidLoad() // 添加通知监听 NotificationCenter.default.addObserver( self, selector: #selector(c_count), name: NSNotification.Name("UpdateCountNotification"), object: nil ) } deinit { // 必须移除监听,防止内存泄漏 NotificationCenter.default.removeObserver(self) } func c_count() { c += 1 print("当前c的值:\(c)") } }
修改SecondViewController
class SecondViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() } @IBAction func button(_ sender: Any) { // 发送通知 NotificationCenter.default.post( name: NSNotification.Name("UpdateCountNotification"), object: nil ) } }
内容的提问来源于stack exchange,提问作者Boo
相关产品推荐
相关产品推荐

