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

UIKit中被Push的ViewController为何自带navigationController?

问题解析:被Push的ViewController为何自动拥有navigationController属性

场景回顾

你最初的SceneDelegate配置中,直接将A_ViewController设为window的根控制器:

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
    guard let windowScene = (scene as? UIWindowScene) else { return }
    let vc = A_ViewController()
    let window = UIWindow(windowScene: windowScene)
    window.rootViewController = vc
    window.makeKeyAndVisible()
    self.window = window
}

此时A_ViewController的navigationController属性为nil,符合预期,因为它不属于任何导航控制器容器。

当你修改为用UINavigationController包裹根控制器后:

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
    guard let windowScene = (scene as? UIWindowScene) else { return }
    let vc = A_ViewController()
    let rootNavigationController = UINavigationController(rootViewController: vc)
    let window = UIWindow(windowScene: windowScene)
    window.rootViewController = rootNavigationController
    window.makeKeyAndVisible()
    self.window = window
}

从A_ViewController推送新的ViewController后,新VC的navigationController属性自动指向当前的导航控制器,这是容器视图控制器的内置行为。

核心原因

UIViewController的navigationController是只读属性,不需要开发者手动初始化。当一个ViewController被加入到UINavigationController的视图控制器栈时,导航控制器会自动完成以下操作:

  • 将该ViewController添加到自身的viewControllers数组中
  • 给该ViewController的navigationController属性赋值为当前的导航控制器实例

这是UINavigationController作为容器视图控制器的核心设计——它负责维护栈内所有VC与自身的关联,让栈内VC能通过navigationController访问导航控制器的功能(如返回、修改导航栏等)。

换句话说,只要ViewController处于某个UINavigationController的栈中,它的navigationController属性就会被自动赋值,无需开发者手动干预。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 23:52:12