You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

删除Main Storyboard后设置UITabBarController为根控制器时出现找不到故事板错误

问题描述

我决定纯用UIKit开发项目,因此删除了Main storyboard,也移除了Info.plist中「Storyboard name」和「Main storyboard file base name」的配置,并修改了SceneDelegate。目前单个ViewController可以正常显示,但尝试设置UITabBarController为根控制器时,出现以下错误:

错误信息
Thread 1: "Could not find a storyboard named 'Main' in bundle NSBundle </Users/[MyDesktopName]/Library/Developer/CoreSimulator/Devices/[ApplicationName]/data/Containers/Bundle/Application/[ApplicationName]/BTY.app> (loaded)"
当前相关代码

BackgroundViewController(原根控制器)

import UIKit

class BackgroundViewController: UIViewController {
    
    let backgroundTabBarController = UITabBarController()

    override func viewDidLoad() {
        super.viewDidLoad()
        
        view.backgroundColor = .white
        createTabBar()
    }
}

extension BackgroundViewController {
    private func createTabBar() {
        view.backgroundColor = .white
        view.addSubview(backgroundTabBarController.view)
        
        let firstViewController = BookSearchViewController()
        let secondViewController = MainViewController()
        let thirdViewController = UserStatusViewController()
        let lastViewController = OrderViewController()
        
        firstViewController.tabBarItem = UITabBarItem(title: "Search", image: UIImage(systemName: "magnifyingglass.circle.fill"), selectedImage: UIImage(systemName: "magnifyingglass.circle"))
//        firstViewController.tabBarItem.tag = 0
        secondViewController.tabBarItem = UITabBarItem(title: "Main", image: UIImage(systemName: "house.fill"), selectedImage: UIImage(systemName: "house"))
//        secondViewController.tabBarItem.tag = 1
        thirdViewController.tabBarItem = UITabBarItem(title: "My", image: UIImage(systemName: "person.fill"), selectedImage: UIImage(systemName: "person"))
//        thirdViewController.tabBarItem.tag = 2
        lastViewController.tabBarItem = UITabBarItem(title: "Order", image: UIImage(systemName: "menucard.fill"), selectedImage: UIImage(systemName: "menucard"))
//        lastViewController.tabBarItem.tag = 3
        
        backgroundTabBarController.viewControllers = [firstViewController, secondViewController, thirdViewController, lastViewController]
        backgroundTabBarController.selectedViewController = secondViewController
    }
}

SceneDelegate

import UIKit

class SceneDelegate: UIResponder, UIWindowSceneDelegate {
    
    var window: UIWindow?

    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
        guard let windowScene = (scene as? UIWindowScene) else { return }
        window = UIWindow(windowScene: windowScene)
        
        window?.rootViewController = BackgroundViewController()
        window?.makeKeyAndVisible()
    }
}
已尝试的解决方法
  • 在SceneDelegate中直接创建UITabBarController并设为根控制器
  • 创建包含UITabBarController的新UIViewController作为根控制器
  • 使用UINavigationController(rootViewController:)包裹视图控制器
  • 从其他ViewController中Present UITabBarController
正确实现方案

1. 彻底清理Info.plist配置

检查并确保Info.plist中所有与storyboard相关的配置项已完全移除:

  • 删除Main storyboard file base name键
  • 进入Application Scene Manifest -> Scene Configuration -> Default Configuration,删除Storyboard Name键

2. 确保所有子ViewController为纯代码初始化

每个自定义ViewController(如BookSearchViewController、MainViewController等)都需要重写初始化方法,避免尝试从storyboard/nib加载:

import UIKit

class MainViewController: UIViewController {
    override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
        super.init(nibName: nil, bundle: nil)
        view.backgroundColor = .white // 初始化视图背景色
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented") // 纯代码开发无需实现该方法
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // 这里添加视图逻辑
    }
}

其他几个子ViewController需要做同样的修改。

3. 直接在SceneDelegate中配置并设置UITabBarController为根控制器

无需用额外的BackgroundViewController包裹,直接在SceneDelegate中完成UITabBarController的配置:

import UIKit

class SceneDelegate: UIResponder, UIWindowSceneDelegate {
    
    var window: UIWindow?

    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
        guard let windowScene = (scene as? UIWindowScene) else { return }
        window = UIWindow(windowScene: windowScene)
        
        // 创建UITabBarController
        let tabBarController = UITabBarController()
        
        // 初始化子控制器
        let searchVC = BookSearchViewController()
        let mainVC = MainViewController()
        let userVC = UserStatusViewController()
        let orderVC = OrderViewController()
        
        // 设置TabBarItem
        searchVC.tabBarItem = UITabBarItem(title: "搜索", image: UIImage(systemName: "magnifyingglass.circle.fill"), selectedImage: UIImage(systemName: "magnifyingglass.circle"))
        mainVC.tabBarItem = UITabBarItem(title: "首页", image: UIImage(systemName: "house.fill"), selectedImage: UIImage(systemName: "house"))
        userVC.tabBarItem = UITabBarItem(title: "我的", image: UIImage(systemName: "person.fill"), selectedImage: UIImage(systemName: "person"))
        orderVC.tabBarItem = UITabBarItem(title: "订单", image: UIImage(systemName: "menucard.fill"), selectedImage: UIImage(systemName: "menucard"))
        
        // 关联子控制器到TabBar
        tabBarController.viewControllers = [searchVC, mainVC, userVC, orderVC]
        tabBarController.selectedViewController = mainVC // 默认选中首页
        
        // 设置为根控制器
        window?.rootViewController = tabBarController
        window?.makeKeyAndVisible()
    }
}

错误原因分析

出现找不到Main storyboard的错误,核心原因是:

  • 某个子ViewController在初始化时,默认尝试通过init?(coder:)方法从storyboard加载(比如这些VC之前是在Main.storyboard中创建的,即使删除了storyboard,代码中仍残留了依赖storyboard的初始化逻辑)
  • Info.plist中可能还有未清理干净的storyboard配置项

内容的提问来源于stack exchange,提问作者Rolf.J

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 02:07:10