如何在非UITabBarController所属的UIViewController上显示同一UITabBar?
解决独立ViewController显示原TabBar的问题
我刚好碰到过类似的场景,核心问题其实是页面层级的归属关系——只有当ViewController处于原UITabBarController的子导航栈中时,才会自动显示TabBar。你现在跳转Profile页面时,是从一个独立的导航栈发起的,自然不会带上TabBar,下面给你几个靠谱的解决方案:
方法一:用原TabBar的子导航控制器发起跳转
这是最推荐的做法,能完美复用原TabBar的状态和逻辑。
在你的TableView cell点击事件里,不要直接用当前VC的导航控制器push,而是先找到原TabBarController的实例,再用它选中的子导航来跳转:
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { // 1. 获取原TabBarController实例(这里用keyWindow的根控制器举例,你也可以通过父控制器链、单例等方式获取) guard let tabBarController = UIApplication.shared.connectedScenes .compactMap({ $0 as? UIWindowScene }) .first?.windows .first(where: { $0.isKeyWindow })?.rootViewController as? UITabBarController, let targetNav = tabBarController.selectedViewController as? UINavigationController else { return } // 2. 从对应Storyboard获取ProfileViewController let profileStoryboard = UIStoryboard(name: "你的Profile所在Storyboard名称", bundle: nil) let profileVC = profileStoryboard.instantiateViewController(withIdentifier: "ProfileViewController") // 3. 关键:用TabBar的子导航控制器push,确保页面在TabBar层级内 targetNav.pushViewController(profileVC, animated: true) }
这样跳转后的Profile页面就会自动显示原TabBar,而且TabBar的选中状态也会和之前保持一致。
方法二:调整Storyboard结构,把独立VC纳入TabBar层级
如果这些独立VC本来就属于某个TabBar标签页的业务流程,那直接在Storyboard里调整结构更省心:
- 确保原TabBarController的每个标签页都是
UINavigationController - 把你那个带两个容器视图的ViewController,设置为对应标签页导航控制器的根ViewController
- 然后直接在Storyboard里给TableView cell添加push segue(跨Storyboard的话用Storyboard引用),这样跳转后的页面自然会继承TabBar
方法三:自定义TabBar全局复用(不推荐,仅特殊场景用)
如果实在需要让完全独立的VC显示相同TabBar,可以自定义一个和原TabBar样式一致的UITabBar,手动添加到目标VC的视图底部。但这种方法需要自己维护TabBar的选中状态、跳转逻辑,很容易和原TabBarController的状态不一致,除非万不得已不建议用:
class ReusableTabBar: UITabBar { // 这里复刻原TabBar的样式、按钮布局等 } // 在独立VC中添加 override func viewDidLoad() { super.viewDidLoad() let tabBar = ReusableTabBar() tabBar.frame = CGRect(x: 0, y: view.bounds.height - 49, width: view.bounds.width, height: 49) // 给TabBar按钮添加点击事件,处理跳转到对应Tab的逻辑 view.addSubview(tabBar) // 避免页面内容被TabBar遮挡 additionalSafeAreaInsets = UIEdgeInsets(top: 0, left: 0, bottom: 49, right: 0) }
最后排查两个常见坑
- 检查ProfileViewController的
hidesBottomBarWhenPushed属性有没有被设为true,如果有改成false(默认就是false,除非你手动设置过) - 确认你获取的导航控制器确实是原TabBarController的子控制器,而不是独立的导航栈
内容的提问来源于stack exchange,提问作者Dani
相关产品推荐
相关产品推荐

