UIKit中被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
相关产品推荐
相关产品推荐

