You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

实现登录登出切换(含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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 10:05:38