You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 22:43:09