返回初始视图控制器时Tab Bar消失问题求助
我来帮你分析下问题根源,再给你几个可行的解决方案:
问题本质
你现在用UIApplication.shared.keyWindow?.rootViewController = loginViewController直接替换了根控制器,这会导致原来的Tab Bar Controller及其下属的所有导航控制器、视图控制器都被系统释放掉(因为没有强引用持有它们)。之后当你试图回到Tab Bar相关页面时,如果只是跳转单个导航控制器,而不是重新构建完整的Tab Bar层级,自然就看不到Tab Bar了——毕竟Tab Bar是Tab Bar Controller的一部分,它已经不存在了。
解决方案
方案1:退出登录时用Present方式(适合需要保留原Tab Bar状态的场景)
如果你只是临时回到登录页(比如退出登录后还要回到原来的Tab Bar状态),不要替换根控制器,而是用全屏Present的方式弹出登录页:
if let loginVC = self.storyboard?.instantiateViewController(withIdentifier: "LoginViewController") { loginVC.modalPresentationStyle = .fullScreen self.present(loginVC, animated: true, completion: nil) }
当用户登录完成后,只需要调用dismiss(animated: true)就能回到原来的Tab Bar页面,Tab Bar会正常显示——因为原层级根本没被销毁。
方案2:登录完成后重新设置Tab Bar为根控制器(适合需要完全重置状态的场景)
如果你的场景是登录后需要全新的Tab Bar状态,那在登录成功时,不要跳转单个导航控制器,而是把根控制器重新设置为完整的Tab Bar Controller:
// 登录成功后执行这段代码切换回Tab Bar if let tabBarVC = self.storyboard?.instantiateViewController(withIdentifier: "TabBarController") as? UITabBarController { // iOS 13+ 正确获取window的方式 if let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene, let window = windowScene.windows.first { window.rootViewController = tabBarVC window.makeKeyAndVisible() } else { // 兼容iOS 12及以下 UIApplication.shared.keyWindow?.rootViewController = tabBarVC } }
注意要在Storyboard里给你的Tab Bar Controller设置正确的Identifier(比如上面代码里的"TabBarController"),这样实例化出来的Tab Bar Controller会带着所有关联的导航控制器和视图,Tab Bar自然会正常显示。
方案3:优化原退出登录的代码(确保层级切换准确)
如果你坚持要用替换根控制器的方式退出登录,那要确保后续回到Tab Bar时,是完整实例化Tab Bar Controller,而不是只实例化某个导航控制器。另外,iOS 13及以后keyWindow可能不准确,建议用场景的方式获取window,就像方案2里的代码那样。
额外提醒
- 检查Storyboard中Tab Bar Controller的配置:确保它正确连接了3个Navigation Controller,每个Navigation Controller的根视图控制器也设置正确。
- 避免直接跳转单个Navigation Controller作为根控制器,因为它不属于Tab Bar Controller的层级,自然不会显示Tab Bar。
内容的提问来源于stack exchange,提问作者Richard Vaněk

