SwiftUI实现登录导航时网络请求成功后无法跳转内容页问题求助
问题根因
你遇到的登录成功后无法跳转到ContentView的问题,核心由两个错误导致:
UserAuth类的ObservableObject实现不符合SwiftUI规范,状态变更无法通知上层视图刷新- 可能存在
UserAuth实例未正确注入整个视图层级的问题
修复步骤
1. 重写UserAuth.swift
SwiftUI的ObservableObject会自动监听@Published修饰的属性变更,无需手动实现willChange/didChange回调,修改后代码如下:
import Combine class UserAuth: ObservableObject { // 用@Published修饰状态变量,变更时自动通知所有监听的视图 @Published var isLoggedin = false func login() { // 登录请求成功后赋值即可 self.isLoggedin = true } }
2. 补全LoginControllerView的属性定义
你当前的代码漏了userAuth属性的修饰符声明,必须用@EnvironmentObject或者@StateObject修饰才能接收状态变更通知,修改后代码如下:
struct LoginControllerView: View { // 从环境中读取UserAuth实例,监听其状态变更 @EnvironmentObject var userAuth: UserAuth var body: some View { Group { if !userAuth.isLoggedin { LoginView() } else { ContentView() } } } }
注意:这里不需要手动给LoginView传userAuth实例,只要父视图注入了环境对象,子视图用@EnvironmentObject就能直接读取
3. 放开LoginView的网络请求逻辑
现在状态监听链路已经通顺,你可以把注释掉的网络请求代码放开,登录成功后修改userAuth.isLoggedin会自动触发LoginControllerView刷新,完成跳转:
struct LoginView: View { @EnvironmentObject var userAuth: UserAuth @StateObject var viewModel = ViewModel<Login>() var body: some View { // 登录页UI代码 Button("登录") { let url = URL(<你的接口地址>)! let encoded = <你的请求参数字符串> let completion = { if viewModel.modelData?.Status == 0 { userAuth.isLoggedin = true let login = viewModel.modelData! if let data = try? JSONEncoder().encode(login) { UserDefaults.standard.set(data, forKey: "LoginData") } } } viewModel.getData(url: url, encoded: encoded, completion: completion) } } }
4. 视图层级注入UserAuth实例
需要在App的入口视图(如果是SwiftUI生命周期就是App结构体的body里,或者是UIKit挂载的根SwiftUI视图)注入全局的UserAuth实例,示例如下:
@main struct MyApp: App { // 全局持有UserAuth实例 @StateObject private var userAuth = UserAuth() var body: some Scene { WindowGroup { LoginControllerView() .environmentObject(userAuth) // 注入到环境中,所有子视图都能读取 } } }
内容的提问来源于stack exchange,提问作者bridgenbarbu
相关产品推荐
相关产品推荐

