Swift登录页面“记住用户”功能无法跳转主界面(window为nil)
登录后自动跳转主页面失败(window为nil问题解决)
问题背景
需要实现登录后“记住用户”并自动跳转到主ViewController,但功能未生效。验证代码逻辑是通的(修改withIdentifier字符串会立刻报错),但添加打印语句后始终输出“window is nil”。已在AppDelegate中声明var window: UIWindow?,代码如下:
let user : String? = UserDefaults.standard.string(forKey: "username") if user != nil { let board : UIStoryboard = UIStoryboard(name: "Main", bundle: nil) let myTag = board.instantiateViewController(withIdentifier: "myTags") as! mainBeaconList print("mainBeaconList: \(myTag)") if let window = window { print("window: \(window)") window.rootViewController = myTag } else { print("window is nil") } }
核心原因与解决方案
window为nil的问题分两种场景,对应不同解决方式:
场景1:iOS12及以下版本
AppDelegate中仅声明了window变量,但未完成初始化。需在application(_:didFinishLaunchingWithOptions:)方法中先初始化window,再执行跳转逻辑:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { // 初始化window并设置为可见 window = UIWindow(frame: UIScreen.main.bounds) window?.makeKeyAndVisible() // 自动跳转逻辑 if let _ = UserDefaults.standard.string(forKey: "username") { let board = UIStoryboard(name: "Main", bundle: nil) let mainVC = board.instantiateViewController(withIdentifier: "myTags") as! mainBeaconList window?.rootViewController = mainVC } else { // 未登录时显示登录页(替换为你的登录页Storyboard ID) let loginVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "LoginVC") window?.rootViewController = loginVC } return true }
场景2:iOS13及以上版本
iOS13后系统窗口管理转移至SceneDelegate,AppDelegate中的window不再生效。需将跳转逻辑移至SceneDelegate的scene(_:willConnectTo:options:)方法:
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { guard let windowScene = (scene as? UIWindowScene) else { return } // 初始化window并设置为可见 let window = UIWindow(windowScene: windowScene) self.window = window window.makeKeyAndVisible() // 自动跳转逻辑 if let _ = UserDefaults.standard.string(forKey: "username") { let board = UIStoryboard(name: "Main", bundle: nil) let mainVC = board.instantiateViewController(withIdentifier: "myTags") as! mainBeaconList window.rootViewController = mainVC } else { // 未登录时显示登录页(替换为你的登录页Storyboard ID) let loginVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "LoginVC") window.rootViewController = loginVC } }
额外注意事项
- 确保Storyboard中ViewController的
Storyboard ID与代码中的"myTags"完全一致,大小写敏感。 - 遵循Swift命名规范,类名首字母大写(如
mainBeaconList改为MainBeaconList),避免类型转换隐患。 - 建议使用
if let user = UserDefaults.standard.string(forKey: "username")这种可选绑定方式,替代if user != nil,代码更安全简洁。
内容的提问来源于stack exchange,提问作者Serdar Percin
相关产品推荐
相关产品推荐

