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

iOS开发问题:返回按钮跳转至错误的视图控制器

问题原因分析

你的问题出在登出逻辑的跳转方式上:你用了pushViewController把登录页推到当前的导航栈里,这就导致原来的导航栈(Screen3 → Screen2 → Screen1 → 导航控制器 → TabBar控制器)后面又追加了一个登录页。当你再次登录后,新的TabBar等页面又被加入到这个已经包含旧登录页的栈里,所以点击返回按钮时,导航栈会回溯到之前的那个登录页,而不是你期望的上一个页面。

解决方案

你需要彻底重置应用的导航栈,而不是在原有栈上追加页面,下面给你两种可行的实现方式:

方式一:用新导航栈包裹登录页作为根控制器(适合登录页需要导航栏的场景)

把你的logOut方法改成下面这样:

@objc func logOut(){ 
    guard let loginView = self.storyboard?.instantiateViewController(withIdentifier: "LoginViewController") as? LoginViewController else { return }
    
    // 创建新的导航栈,仅包含登录页
    let newNavController = UINavigationController(rootViewController: loginView)
    loginView.navigationItem.hidesBackButton = true
    
    // 获取当前窗口,替换根控制器并添加过渡动画
    if let scene = UIApplication.shared.connectedScenes.first as? UIWindowScene,
       let window = scene.windows.first {
        window.rootViewController = newNavController
        UIView.transition(with: window, duration: 0.3, options: .transitionCrossDissolve, animations: nil)
    }
}

方式二:直接将登录页设为根控制器(适合登录页不需要导航栏的场景)

如果你的登录页本身不需要导航栏,可以简化成:

@objc func logOut(){ 
    guard let loginView = self.storyboard?.instantiateViewController(withIdentifier: "LoginViewController") as? LoginViewController else { return }
    
    // 直接替换根控制器
    if let scene = UIApplication.shared.connectedScenes.first as? UIWindowScene,
       let window = scene.windows.first {
        window.rootViewController = loginView
        UIView.transition(with: window, duration: 0.3, options: .transitionCrossDissolve, animations: nil)
    }
}

额外提醒:登录成功后的跳转也要注意

登录成功跳转到TabBar控制器时,同样要用替换根控制器的方式,而不是push,避免再次出现栈混乱:

// 登录成功后的跳转代码示例
guard let tabBarVC = storyboard?.instantiateViewController(withIdentifier: "TabBarController") as? UITabBarController else { return }
if let scene = UIApplication.shared.connectedScenes.first as? UIWindowScene,
   let window = scene.windows.first {
    window.rootViewController = tabBarVC
    UIView.transition(with: window, duration: 0.3, options: .transitionCrossDissolve, animations: nil)
}
总结

核心就是不要在原有导航栈上追加登录页,而是彻底重置整个应用的根控制器,这样再次登录后的导航栈就是干净的,返回按钮就能正常按你期望的层级回溯了。

内容的提问来源于stack exchange,提问作者Michael R

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 08:11:10