登录成功后无法关闭UIViewController问题求助
问题分析与解决方案
首先要明确一个核心点:你是用present(_:animated:completion:)弹出的LoginController,它属于模态视图控制器,根本不在你的主导航栈里。所以你之前尝试的navigationController?.pushViewController完全不适用,而dismiss没生效大概率是逻辑或者引用问题导致的。
为什么你的原有代码不工作?
self.navigationController?.pushViewController(navController, animated: true):因为LoginController是被模态弹出的,它本身没有被嵌入到任何导航控制器中,所以self.navigationController的值是nil,这行代码根本不会执行。- 你注释掉的
self.dismiss如果没生效,很大可能是闭包里的self存在强引用问题,导致回调没有正确触发;或者你在dismiss后没有正确回到主导航栈去跳转页面。
正确的解决办法
方案1:关闭登录控制器后,回到原导航栈并跳转Profile页面
适合登录后需要回到原来的导航流程的场景:
Auth.auth().signIn(withEmail: email, password: password) { [weak self] (user, err) in // 先处理self的弱引用,避免循环引用和野指针 guard let self = self else { return } if let err = err { print("Failed to sign in user with email", err ) return } // 先关闭模态的登录控制器,在完成回调里处理页面跳转 self.dismiss(animated: true) { // 获取弹出当前登录控制器的那个控制器,它的navigationController就是主导航栈 if let mainNav = self.presentingViewController?.navigationController { let userProfileVC = UserProfileController() mainNav.pushViewController(userProfileVC, animated: true) } } }
方案2:直接替换根视图控制器(登录后进入全新主界面)
如果登录后不需要回到之前的页面,直接进入用户Profile作为主界面:
Auth.auth().signIn(withEmail: email, password: password) { [weak self] (user, err) in guard let self = self else { return } if let err = err { print("Failed to sign in user with email", err ) return } self.dismiss(animated: true) { let userProfileVC = UserProfileController() let navController = UINavigationController(rootViewController: userProfileVC) // 获取当前应用的主窗口,替换根控制器 if let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene, let mainWindow = windowScene.windows.first { mainWindow.rootViewController = navController mainWindow.makeKeyAndVisible() } } }
关键注意点
- 一定要在Firebase的回调闭包里使用
[weak self],避免循环引用导致内存泄漏,同时保证回调执行时self是有效的。 - 模态视图控制器只能用
dismiss来关闭,不能用导航栈的push/pop方法操作,这是iOS视图控制器的基础规则哦。
内容的提问来源于stack exchange,提问作者unicorn_surprise
相关产品推荐
相关产品推荐

