如何在Xcode Storyboard根视图控制器前按需插入引导视图控制器?
实现方案
1. 调整Storyboard的初始控制器
把你原来的自定义UIViewController的「Is Initial View Controller」勾选取消,然后添加一个空白UIViewController作为新的初始控制器——这个VC只做中转用,不需要任何界面元素。
2. 中转VC里做逻辑判断与加载控制
在这个中转VC的viewDidAppear方法里,先判断是否需要展示引导类页面(比如用UserDefaults记录用户是否看过引导、是否触发付费墙条件),然后分情况处理:
class LaunchRouterVC: UIViewController { override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) // 替换成你的实际判断逻辑:要不要显示引导页 let needShowOnboarding = UserDefaults.standard.bool(forKey: "ShouldShowOnboarding") if needShowOnboarding { // 加载引导控制器 let onboardingVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "OnboardingVC") as! OnboardingVC onboardingVC.modalPresentationStyle = .fullScreen // 设置关闭后的回调 onboardingVC.dismissCompletion = { [weak self] in self?.loadMainVC() } present(onboardingVC, animated: true) } else { // 直接加载主控制器 loadMainVC() } } private func loadMainVC() { // 后台加载主控制器,避免阻塞主线程 DispatchQueue.global(qos: .userInitiated).async { let mainVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "MainVC") as! MainViewController DispatchQueue.main.async { // 替换根控制器为加载好的主VC guard let keyWindow = UIApplication.shared.windows.first(where: { $0.isKeyWindow }) else { return } keyWindow.rootViewController = mainVC keyWindow.makeKeyAndVisible() } } } }
3. 引导控制器的回调处理
给引导VC加个闭包属性,用来在关闭时通知中转VC去加载主控制器:
class OnboardingVC: UIViewController { // 定义关闭回调 var dismissCompletion: (() -> Void)? // 关闭引导页的按钮点击事件 @IBAction func closeBtnTapped(_ sender: UIButton) { // 标记用户已看过引导,下次不再展示 UserDefaults.standard.set(false, forKey: "ShouldShowOnboarding") dismiss(animated: true) { [weak self] in self?.dismissCompletion?() } } }
4. 关键细节注意
- 中转VC要设透明背景:在Storyboard里把它的背景色改成
Clear Color,避免启动时出现闪屏。 - 主控制器放在后台加载:因为你提到它加载耗时约1秒,后台加载不会阻塞主线程,能提升启动流畅度。
- 如果引导是视图而非控制器:可以直接在中转VC上添加引导视图,关闭后再调用
loadMainVC(),逻辑和上面一致。
内容的提问来源于stack exchange,提问作者Deepak Sharma
相关产品推荐
相关产品推荐

