如何创建仅首次启动时显示的ViewController?
嘿,这个需求在App开发里太常见啦!我来给你分享几种实用的实现思路,核心就是通过本地存储标记用户是否已经完成过昵称设置,然后在App启动时根据这个标记决定展示哪个页面~
核心思路
我们需要一个持久化的“开关”,记录用户是否已经完成昵称设置:
- 首次启动App时,这个开关是“关闭”状态,展示昵称设置页面
- 用户完成设置后,把开关拨到“开启”状态
- 后续启动App时,检测到开关是“开启”,直接跳转到主页面
方法一:使用UserDefaults(最推荐,轻量快捷)
UserDefaults是iOS里最适合存储这种轻量状态的工具,操作简单,数据会持久化保存到本地,直到App被删除。
步骤1:在App启动时判断状态
你需要在App的入口逻辑里(比如AppDelegate的didFinishLaunchingWithOptions,或者iOS13+的SceneDelegate的scene(_:willConnectTo:options:))添加判断逻辑:
// 以AppDelegate为例(iOS12及以下) func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { let defaults = UserDefaults.standard // 读取是否已设置昵称的标记,默认是false(首次启动) let hasSetNickname = defaults.bool(forKey: "hasSetNickname") let window = UIWindow(frame: UIScreen.main.bounds) self.window = window if !hasSetNickname { // 首次启动,展示昵称设置页面 let nicknameVC = NicknameSetupViewController() // 如果需要导航栏,可以包一层UINavigationController window.rootViewController = UINavigationController(rootViewController: nicknameVC) } else { // 已完成设置,展示主页面 let mainVC = MainTabBarController() // 替换成你的主页面VC window.rootViewController = mainVC } window.makeKeyAndVisible() return true } // iOS13+用SceneDelegate的写法 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 defaults = UserDefaults.standard let hasSetNickname = defaults.bool(forKey: "hasSetNickname") if !hasSetNickname { let nicknameVC = NicknameSetupViewController() window.rootViewController = UINavigationController(rootViewController: nicknameVC) } else { let mainVC = MainTabBarController() window.rootViewController = mainVC } window.makeKeyAndVisible() }
步骤2:完成昵称设置后更新标记
在昵称设置页面的确认按钮点击事件里,保存用户输入的昵称(如果需要),并更新标记:
class NicknameSetupViewController: UIViewController { @IBOutlet weak var nicknameTextField: UITextField! @IBAction func confirmButtonTapped(_ sender: UIButton) { guard let nickname = nicknameTextField.text?.trimmingCharacters(in: .whitespaces), !nickname.isEmpty else { // 提示用户输入有效的昵称 let alert = UIAlertController(title: "提示", message: "请输入你的昵称", preferredStyle: .alert) alert.addAction(UIAlertAction(title: "确定", style: .default)) present(alert, animated: true) return } // 1. 保存用户昵称(可选,根据你的需求) UserDefaults.standard.set(nickname, forKey: "userNickname") // 2. 标记已完成昵称设置 UserDefaults.standard.set(true, forKey: "hasSetNickname") // iOS10+之后UserDefaults会自动同步到本地,这行可以省略,但加上也没问题 UserDefaults.standard.synchronize() // 3. 跳转到主页面 let mainVC = MainTabBarController() // 如果你用了导航栏,也可以用push或者popToRootViewController,这里直接替换根视图更彻底 UIApplication.shared.keyWindow?.rootViewController = UINavigationController(rootViewController: mainVC) } }
方法二:使用Keychain(适合需要跨App删除保留的场景)
如果你的需求是即使用户删除App重装,也不想再显示昵称设置页面(这种场景比较少,比如绑定了用户账号的情况),可以用Keychain来存储标记。不过Keychain的操作比UserDefaults复杂一点,你可以封装一个工具类来简化:
// 简单的Keychain工具类示例 class KeychainHelper { static let shared = KeychainHelper() private let service = "com.yourapp.nickname" private let account = "nicknameStatus" func saveStatus(_ status: Bool) { let data = Data(bytes: &status, count: MemoryLayout<Bool>.size) let query: [String: Any] = [ kSecClass as String: kSecClassGenericPassword, kSecAttrService as String: service, kSecAttrAccount as String: account, kSecValueData as String: data ] // 先删除旧数据(如果有) SecItemDelete(query as CFDictionary) // 添加新数据 SecItemAdd(query as CFDictionary, nil) } func getStatus() -> Bool { let query: [String: Any] = [ kSecClass as String: kSecClassGenericPassword, kSecAttrService as String: service, kSecAttrAccount as String: account, kSecReturnData as String: kCFBooleanTrue!, kSecMatchLimit as String: kSecMatchLimitOne ] var data: AnyObject? let status = SecItemCopyMatching(query as CFDictionary, &data) if status == errSecSuccess, let data = data as? Data { var statusBool = false data.copyBytes(to: &statusBool, count: MemoryLayout<Bool>.size) return statusBool } return false } } // 使用方式和UserDefaults类似,启动时判断: let hasSetNickname = KeychainHelper.shared.getStatus() // 完成设置后: KeychainHelper.shared.saveStatus(true)
方法三:使用Core Data(若已有用户数据体系)
如果你的App已经在用Core Data存储用户相关数据,可以在用户实体里加一个isNicknameSet的布尔字段,启动时查询这个字段来判断是否展示设置页面。这种方式适合有复杂用户数据管理的场景,思路和前面一致:查询字段状态→决定页面→更新字段。
注意事项
- 测试首次启动效果时,记得删除App后再重新安装,因为UserDefaults/Keychain的数据会保留到App被删除
- 如果你的App支持多场景(iPad多窗口),要确保在每个场景启动时都做同样的判断
- UserDefaults不要用来存储敏感数据,昵称这种非敏感信息完全没问题
内容的提问来源于stack exchange,提问作者ilija.trkulja
相关产品推荐
相关产品推荐

