SwiftUI变量状态更新问题:NavigationStack无法跳转至下一页
问题分析
你的代码核心问题在于LoginViewModel的isValid和LoginService的isValid是完全独立的两个状态变量:登录成功后,LoginService更新的是自身的isValid,但LoginViewModel的isValid从未被修改。而NavigationStack监听的是$loginViewModel.isValid,这个值始终为false,因此跳转逻辑无法触发。
修复方案
方案一:让ViewModel监听Service的状态变化
修改LoginViewModel,通过监听LoginService的isValid变化,同步更新自身状态:
class LoginViewModel: ObservableObject { @Published var username: String = "" @Published var password: String = "" @Published var isValid: Bool = false @ObservedObject var loginService = LoginService() init() { // 同步Service的isValid状态到当前ViewModel loginService.$isValid .assign(to: &$isValid) } func login() { loginService.username = username loginService.password = password loginService.loginUser() } }
同时建议把LoginView中的@ObservedObject替换为@StateObject,确保ViewModel生命周期与View一致:
struct LoginView: View { @StateObject var loginViewModel = LoginViewModel() // ... 其余代码不变 }
方案二:通过闭包回调传递登录结果(更符合MVVM职责划分)
这种方式取消Service内部的状态管理,改为通过闭包将登录结果传递给ViewModel,由ViewModel控制视图跳转:
第一步:修改LoginService
class LoginService { // 移除不需要的@Published变量,结果通过闭包返回 func loginUser(username: String, password: String, completion: @escaping (Bool) -> Void) { PFUser.logInWithUsername(inBackground: username, password: password) { (pfUser, error) in DispatchQueue.main.async { // 登录成功的条件:无错误且用户对象存在 let success = error == nil && pfUser != nil completion(success) } } } }
第二步:修改LoginViewModel
class LoginViewModel: ObservableObject { @Published var username: String = "" @Published var password: String = "" @Published var isValid: Bool = false let loginService = LoginService() func login() { loginService.loginUser(username: username, password: password) { [weak self] success in self?.isValid = success } } }
内容的提问来源于stack exchange,提问作者Oleksandr Matrosov
相关产品推荐
相关产品推荐

