iOS Swift中代码结合IBOutlet创建UITabBar不显示视图控制器的解决方法
问题分析与修复方案
你的代码存在几个核心问题,导致TabBar无法正常加载并显示ViewController:
1. 复制粘贴错误
创建secondVC时,错误地对firstVC重复赋值,所有属性操作都应指向secondVC本身:
// 原错误代码 let secondVC = SecondViewController() firstVC.name = nameVal // 应为 secondVC.name = nameVal firstVC.tabBarItem = ... // 应为 secondVC.tabBarItem = ...
2. TabBar条目赋值类型错误
UITabBar.items需要的是UITabBarItem类型数组,你直接传入了UIViewController数组,TabBar无法识别正确的条目。正确做法是提取每个VC的tabBarItem:
// 原错误代码 tabBarCnt.items = [firstVC, secondVC, thirdVC] // 修正后 tabBarCnt.items = [firstVC.tabBarItem, secondVC.tabBarItem, thirdVC.tabBarItem]
3. 未管理ViewController的显示逻辑
你仅创建了VC实例,但没有将它们添加为当前控制器的子控制器,也未实现TabBar切换时的VC显示/隐藏逻辑。
方案一:改用系统UITabBarController(推荐)
系统UITabBarController会自动处理VC的管理和切换,实现更简洁:
public class TabBarViewController: UITabBarController { override public func viewDidLoad() { super.viewDidLoad() self.delegate = self setupTabBarItems() } func setupTabBarItems() { // 第一个页面 let firstVC = FirstViewController() firstVC.name = nameVal let firstTab = UITabBarItem(title: nil, image: UIImage(named: "ico_active", in: Bundle(for: Self.self), compatibleWith: nil), tag: 0) firstTab.imageInsets = UIEdgeInsets(top: 5, left: 0, bottom: -5, right: 0) firstVC.tabBarItem = firstTab // 第二个页面 let secondVC = SecondViewController() secondVC.name = nameVal let secondTab = UITabBarItem(title: nil, image: UIImage(named: "ico_active", in: Bundle(for: Self.self), compatibleWith: nil), tag: 1) secondTab.imageInsets = UIEdgeInsets(top: 5, left: 0, bottom: -5, right: 0) secondVC.tabBarItem = secondTab // 第三个页面 let thirdVC = ThirdViewController() thirdVC.name = nameVal let thirdTab = UITabBarItem(title: nil, image: UIImage(named: "ico_active", in: Bundle(for: Self.self), compatibleWith: nil), tag: 2) thirdTab.imageInsets = UIEdgeInsets(top: 5, left: 0, bottom: -5, right: 0) thirdVC.tabBarItem = thirdTab // 将页面添加到TabBarController self.viewControllers = [firstVC, secondVC, thirdVC] } } // 可选:实现切换事件监听 extension TabBarViewController: UITabBarControllerDelegate { func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) { // 处理页面切换后的逻辑 } }
方案二:修复自定义UIViewController+UITabBar的实现
如果坚持手动管理TabBar,需要添加子控制器并实现切换逻辑:
public class TabBarViewController: UIViewController, UITabBarDelegate { @IBOutlet weak var tabBarCnt: UITabBar! private var childVCs: [UIViewController] = [] private var currentShowVC: UIViewController? override public func viewDidLoad() { super.viewDidLoad() tabBarCnt.delegate = self setupTabBarAndVCs() // 默认显示第一个页面 if let firstVC = childVCs.first { switchToVC(firstVC) } } func setupTabBarAndVCs() { // 初始化三个页面 let firstVC = FirstViewController() firstVC.name = nameVal firstVC.tabBarItem = createTabItem(tag: 0) let secondVC = SecondViewController() secondVC.name = nameVal secondVC.tabBarItem = createTabItem(tag: 1) let thirdVC = ThirdViewController() thirdVC.name = nameVal thirdVC.tabBarItem = createTabItem(tag: 2) childVCs = [firstVC, secondVC, thirdVC] tabBarCnt.items = childVCs.map { $0.tabBarItem! } } // 封装TabBarItem创建逻辑 private func createTabItem(tag: Int) -> UITabBarItem { let tabItem = UITabBarItem(title: nil, image: UIImage(named: "ico_active", in: Bundle(for: Self.self), compatibleWith: nil), tag: tag) tabItem.imageInsets = UIEdgeInsets(top: 5, left: 0, bottom: -5, right: 0) return tabItem } // 切换页面逻辑 private func switchToVC(_ targetVC: UIViewController) { // 移除当前页面 currentShowVC?.view.removeFromSuperview() currentShowVC?.removeFromParent() // 添加目标页面 addChild(targetVC) targetVC.view.frame = CGRect(x: 0, y: 0, width: view.bounds.width, height: view.bounds.height - tabBarCnt.bounds.height) view.insertSubview(targetVC.view, belowSubview: tabBarCnt) targetVC.didMove(toParent: self) currentShowVC = targetVC } // TabBar切换回调 func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) { guard let targetVC = childVCs.first(where: { $0.tabBarItem?.tag == item.tag }) else { return } switchToVC(targetVC) } }
内容的提问来源于stack exchange,提问作者PvUIDev
相关产品推荐
相关产品推荐

