如何以编程方式使用UINavigationController?按钮跳转失败问题
问题分析与解决方案
问题根源
- 当前
ViewController未处于UINavigationController的导航栈中,导致self.navigationController为nil,可选链调用pushViewController直接跳过,无任何执行动作。 - 错误地将目标控制器包装成
UINavigationController再执行push,这不符合导航栈的使用逻辑。
解决步骤
第一步:让当前控制器进入导航栈(二选一)
因为push跳转必须在导航栈中进行,你需要先让当前ViewController成为导航控制器的子控制器:
- 方式1:通过Storyboard设置
选中当前ViewController,点击Xcode顶部菜单栏Editor->Embed In->Navigation Controller,此时当前控制器会自动成为导航控制器的根控制器。 - 方式2:通过代码设置(适用于当前控制器是根控制器的场景)
在SceneDelegate的scene(_:willConnectTo:options:)方法中,将当前控制器包裹进导航控制器后设为根控制器:func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { guard let windowScene = (scene as? UIWindowScene) else { return } let window = UIWindow(windowScene: windowScene) self.window = window let storyboard = UIStoryboard(name: "Main", bundle: nil) // 替换成你当前ViewController的标识符 let mainVC = storyboard.instantiateViewController(withIdentifier: "YourCurrentVCID") as! YourCurrentViewController let navController = UINavigationController(rootViewController: mainVC) window.rootViewController = navController window.makeKeyAndVisible() }
第二步:修正按钮点击事件代码
移除多余的导航控制器包装,直接push目标控制器:
@IBAction func editBtn(_ sender: Any) { let storyBoard = UIStoryboard(name: "Main", bundle: nil) // 用guard避免强制解包崩溃,增加容错性 guard let newViewController = storyBoard.instantiateViewController(withIdentifier: "editProfile") as? editProfile else { print("实例化editProfile控制器失败") return } self.navigationController?.pushViewController(newViewController, animated: true) }
内容的提问来源于stack exchange,提问作者Heli Bhadeshiya
相关产品推荐
相关产品推荐

