如何实现UITabBarController中仅启动可见的隐藏欢迎页面?
Hey there! Let's figure out how to add that one-time welcome page to your UITabBarController setup. I'll cover both Storyboard and code-based solutions since you asked about both—plus explain why your earlier attempt might not have worked.
Here's how to set this up using Storyboard:
Design your welcome page
- Add a new
UIViewControllerto your Storyboard, customize its layout (add a welcome message, "Enter App" button, etc.), and give it a Storyboard ID likeWelcomeViewController. - Make sure your existing
UITabBarControllerhas a Storyboard ID too (e.g.,MainTabBarController).
- Add a new
Control root controller on app launch
- Open your
SceneDelegate.swift(orAppDelegate.swiftif you're using an older project structure). - In the
scene(_:willConnectTo:options:)method, check if the user has already seen the welcome page usingUserDefaults:func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { guard let windowScene = (scene as? UIWindowScene) else { return } let window = UIWindow(windowScene: windowScene) self.window = window // Check if welcome page was already shown let hasShownWelcome = UserDefaults.standard.bool(forKey: "hasShownWelcomePage") if hasShownWelcome { // Show TabBarController directly let tabBarVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "MainTabBarController") as! UITabBarController window.rootViewController = tabBarVC } else { // Show welcome page first let welcomeVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "WelcomeViewController") as! WelcomeViewController window.rootViewController = welcomeVC } window.makeKeyAndVisible() }
- Open your
Add transition logic to welcome page
- Connect your "Enter App" button to an action in the welcome view controller:
@IBAction func enterAppButtonTapped(_ sender: UIButton) { // Mark welcome page as shown UserDefaults.standard.set(true, forKey: "hasShownWelcomePage") // Load TabBarController and set it as root guard let tabBarVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "MainTabBarController") as? UITabBarController else { return } // Replace root controller (no way to go back to welcome page) UIApplication.shared.keyWindow?.rootViewController = tabBarVC }
- Connect your "Enter App" button to an action in the welcome view controller:
If you prefer a code-only approach, here's how to do it:
Create your welcome view controller
class WelcomeViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() view.backgroundColor = .white // Add "Enter App" button let enterButton = UIButton(type: .system) enterButton.setTitle("Enter App", for: .normal) enterButton.addTarget(self, action: #selector(enterAppTapped), for: .touchUpInside) enterButton.translatesAutoresizingMaskIntoConstraints = false view.addSubview(enterButton) NSLayoutConstraint.activate([ enterButton.centerXAnchor.constraint(equalTo: view.centerXAnchor), enterButton.centerYAnchor.constraint(equalTo: view.centerYAnchor) ]) } @objc private func enterAppTapped() { UserDefaults.standard.set(true, forKey: "hasShownWelcomePage") let tabBarVC = createTabBarController() UIApplication.shared.keyWindow?.rootViewController = tabBarVC } }Create your TabBarController programmatically
func createTabBarController() -> UITabBarController { let tabBarVC = UITabBarController() // Create your 5 tab view controllers let tab1VC = UIViewController() tab1VC.tabBarItem = UITabBarItem(title: "Tab 1", image: UIImage(systemName: "house"), tag: 0) tab1VC.view.backgroundColor = .red let tab2VC = UIViewController() tab2VC.tabBarItem = UITabBarItem(title: "Tab 2", image: UIImage(systemName: "person"), tag: 1) tab2VC.view.backgroundColor = .blue // Repeat for tabs 3,4,5... tabBarVC.viewControllers = [tab1VC, tab2VC, tab3VC, tab4VC, tab5VC] return tabBarVC }Set root controller on launch
InSceneDelegate.swift:func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { guard let windowScene = (scene as? UIWindowScene) else { return } let window = UIWindow(windowScene: windowScene) self.window = window let hasShownWelcome = UserDefaults.standard.bool(forKey: "hasShownWelcomePage") if hasShownWelcome { window.rootViewController = createTabBarController() } else { window.rootViewController = WelcomeViewController() } window.makeKeyAndVisible() }
When you set the welcome view controller as the root directly but didn't properly switch to the UITabBarController afterwards, the tab bar never got loaded as the root. Using root controller replacement (instead of presenting or pushing) ensures the welcome page is completely removed from the view hierarchy—so users can't navigate back to it by switching tabs or using the back button.
内容的提问来源于stack exchange,提问作者Shinox

