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

iOS中UINavigationController返回后如何调用ViewController1的方法?

解决方法:让ViewController1从ViewController2返回时自动执行方法

不用UINavigationControllerDelegate的话,有几个更轻量的方案,你可以根据需求选择:

1. 利用ViewController的生命周期方法(最简单,无需修改VC2)

viewWillAppear(_:) 或 viewDidAppear(_:) 会在ViewController被显示时触发,自然也包括从VC2 pop回来的场景。唯一要注意的是首次加载VC1时也会触发,所以加个标记区分即可:

class ViewController1: UIViewController {
    // 标记是否是首次加载页面
    private var isFirstAppearance = true

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        
        if !isFirstAppearance {
            // 这里写从VC2返回后要执行的操作
            performPostReturnAction()
        }
        // 首次加载完成后,把标记设为false
        isFirstAppearance = false
    }

    private func performPostReturnAction() {
        print("从VC2回来了,执行预设操作!")
        // 你的业务逻辑代码写在这里
    }
}

这个方案零额外依赖,只需要在VC1里加几行代码,非常省心。

2. 闭包回调(最精准,可控性强)

如果希望只有在从VC2返回时才触发(避免其他场景误触发),可以给VC2加一个回调闭包,在它即将被pop时调用:

首先在ViewController2里定义闭包:

class ViewController2: UIViewController {
    // 定义回调闭包,用weak避免循环引用风险
    var onWillPop: (() -> Void)?

    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        // 判断当前是否是被从导航栈中移除(也就是执行了pop操作)
        if isMovingFromParent {
            onWillPop?()
        }
    }

    // 如果是自己手动调用pop的方法,也可以直接在pop前触发闭包
    @objc private func manualPop() {
        navigationController?.popViewController(animated: true)
        onWillPop?()
    }
}

然后在ViewController1 push VC2时,设置这个闭包:

class ViewController1: UIViewController {
    private func pushToVC2() {
        let vc2 = ViewController2()
        // 用[weak self]避免循环引用
        vc2.onWillPop = { [weak self] in
            self?.performPostReturnAction()
        }
        navigationController?.pushViewController(vc2, animated: true)
    }

    private func performPostReturnAction() {
        print("从VC2回来了,执行预设操作!")
        // 你的业务逻辑代码写在这里
    }
}

这个方案的好处是完全可控,只有当VC2被pop时才会触发,不会被其他显示场景干扰。

3. NotificationCenter通知(适合跨多层页面的场景)

如果VC1和VC2之间隔了多层导航,或者需要全局监听返回事件,可以用通知:

在ViewController1里注册通知:

class ViewController1: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        // 注册通知监听
        NotificationCenter.default.addObserver(
            self,
            selector: #selector(handleReturnFromVC2),
            name: NSNotification.Name("ReturnedFromVC2"),
            object: nil
        )
    }

    @objc private func handleReturnFromVC2() {
        performPostReturnAction()
    }

    private func performPostReturnAction() {
        print("从VC2回来了,执行预设操作!")
    }

    // 记得在页面销毁时移除监听,避免内存泄漏
    deinit {
        NotificationCenter.default.removeObserver(self)
    }
}

在ViewController2里发送通知:

class ViewController2: UIViewController {
    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        if isMovingFromParent {
            // 发送返回通知
            NotificationCenter.default.post(
                name: NSNotification.Name("ReturnedFromVC2"),
                object: nil
            )
        }
    }
}

不过这个方案是全局通知,不如闭包精准,除非必要,优先选前两种。


内容的提问来源于stack exchange,提问作者Mark Meretzky

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 14:22:39