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

Swift 5添加SceneDelegate后根视图切换失效,登出功能异常

问题描述

添加SceneDelegate并迁移AppDelegate代码后,登出功能出现异常:点击登出按钮无即时反应,但关闭并重新打开应用后,用户会被正常登出。怀疑问题出在登出函数中使用的共享代理逻辑上。

相关代码

首页登出按钮代码

@IBAction func signOutButtonTapped(_ sender: Any) {
    KeychainWrapper.standard.removeObject(forKey: "accessToken")
    KeychainWrapper.standard.removeObject(forKey: "userID")
    
    // send user to splash page
    let signInPage = self.storyboard?.instantiateViewController(withIdentifier: "splashController") as! splashViewController
    let appDelegate = UIApplication.shared.delegate
    appDelegate?.window??.rootViewController = signInPage
    
}

SceneDelegate.swift代码

class SceneDelegate: UIResponder, UIWindowSceneDelegate {

    var window: UIWindow?

    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
        
        guard let _ = (scene as? UIWindowScene) else { return }

        let accessToken: String? = KeychainWrapper.standard.string(forKey: "accessToken")
        
        // If access token exists, skip login page
        if accessToken != nil {            
            if let windowScene = scene as? UIWindowScene {
                self.window = UIWindow(windowScene: windowScene)
                let mainStoryboard:UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
                let vc = mainStoryboard.instantiateViewController(withIdentifier: "homeTabController") as! TabBarController
                self.window!.rootViewController = vc
            }        
        }    

    }
  }
解决方案

问题核心:iOS 13+ 采用多场景架构后,AppDelegate不再负责窗口管理,实际窗口控制权已移交SceneDelegate。你当前的登出代码仍在尝试通过UIApplication.shared.delegate获取窗口,导致修改根控制器的操作无法作用到当前活跃窗口。

修复登出函数(单场景应用)

直接获取当前活跃场景的SceneDelegate,更新其窗口的根控制器:

@IBAction func signOutButtonTapped(_ sender: Any) {
    KeychainWrapper.standard.removeObject(forKey: "accessToken")
    KeychainWrapper.standard.removeObject(forKey: "userID")
    
    // 获取当前活跃场景的SceneDelegate及窗口
    guard let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene,
          let sceneDelegate = windowScene.delegate as? SceneDelegate,
          let window = sceneDelegate.window else {
        return
    }
    
    // 跳转至启动页
    let signInPage = self.storyboard?.instantiateViewController(withIdentifier: "splashController") as! splashViewController
    window.rootViewController = signInPage
    window.makeKeyAndVisible() // 确保窗口切换后可见
}

多场景支持优化(如iPad分屏)

如果应用支持多场景,遍历所有活跃场景并统一更新根控制器:

@IBAction func signOutButtonTapped(_ sender: Any) {
    KeychainWrapper.standard.removeObject(forKey: "accessToken")
    KeychainWrapper.standard.removeObject(forKey: "userID")
    
    let signInPage = self.storyboard?.instantiateViewController(withIdentifier: "splashController") as! splashViewController
    
    // 遍历所有活跃场景,统一切换登录页面
    for scene in UIApplication.shared.connectedScenes {
        guard let windowScene = scene as? UIWindowScene,
              let sceneDelegate = windowScene.delegate as? SceneDelegate,
              let window = sceneDelegate.window else {
            continue
        }
        window.rootViewController = signInPage
        window.makeKeyAndVisible()
    }
}

内容的提问来源于stack exchange,提问作者Two Chains

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 17:25:29