实现登录登出切换(含UserDefaults存状态)时第二页面导航栏不显示
解决导航栏不显示+登录状态持久化问题
我来帮你搞定这两个问题:首先是SignOutPage没有导航栏的问题,然后是用UserDefaults记录登录状态的逻辑。
问题根源
你现在用present方法来跳转页面,这种方式会把新控制器以模态弹窗的形式展示,它不属于原导航控制器的栈结构,所以自然不会显示导航栏。另外你还没实现登录状态的持久化逻辑,启动时也没根据状态判断初始页面。
完整解决方案
下面是修改后的代码,我会把关键改动标出来:
1. 封装登录状态管理工具(让逻辑更清晰)
新建一个AuthManager类统一处理登录状态,也可以直接用UserDefaults操作,但封装后更易维护:
import Foundation class AuthManager { static let shared = AuthManager() private let userDefaults = UserDefaults.standard private let isLoggedInKey = "isLoggedIn" var isLoggedIn: Bool { get { return userDefaults.bool(forKey: isLoggedInKey) } set { userDefaults.set(newValue, forKey: isLoggedInKey) } } }
2. 修改AppDelegate,启动时根据登录状态加载页面
import UIKit @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { // 根据登录状态自动选择初始页面 let initialVC = AuthManager.shared.isLoggedIn ? SignOutPage() : LoginPage() theViewController(controllerIs: initialVC) return true } fileprivate func theViewController(controllerIs: UIViewController) { window = UIWindow(frame: UIScreen.main.bounds) window?.makeKeyAndVisible() window?.rootViewController = UINavigationController(rootViewController: controllerIs) } }
3. 修改LoginPage的登录逻辑,替换根控制器并更新状态
import UIKit class LoginPage: UIViewController { override func viewDidLoad() { super.viewDidLoad() view.backgroundColor = .green navigationItem.leftBarButtonItem = UIBarButtonItem(title: "Login", style: .plain, target: self, action: #selector(handleLogin)) } @objc private func handleLogin() { // 标记用户已登录 AuthManager.shared.isLoggedIn = true // 替换根控制器,让SignOutPage处于导航栈中(这样导航栏会正常显示) let navController = UINavigationController(rootViewController: SignOutPage()) UIApplication.shared.keyWindow?.rootViewController = navController } }
4. 修改SignOutPage的登出逻辑,同样替换根控制器并更新状态
import UIKit class SignOutPage: UIViewController { override func viewDidLoad() { super.viewDidLoad() view.backgroundColor = .yellow navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Sign Out", style: .plain, target: self, action: #selector(handleSignOut)) } @objc private func handleSignOut() { // 标记用户已登出 AuthManager.shared.isLoggedIn = false // 替换根控制器回到登录页 let navController = UINavigationController(rootViewController: LoginPage()) UIApplication.shared.keyWindow?.rootViewController = navController } }
关键说明
- 用
替换根控制器的方式跳转,保证新页面处于导航控制器的栈中,导航栏就能正常显示了。 AuthManager封装了UserDefaults的操作,让登录状态的管理更清晰、可复用。- 启动时会自动读取保存的登录状态,加载对应的页面,实现状态持久化的效果。
内容的提问来源于stack exchange,提问作者Ilie
相关产品推荐
相关产品推荐

