iOS15 SwiftUI 异步命令中通过条件语句切换视图不生效问题咨询
问题原因
在Button的Task闭包中直接初始化Dashboard()/ContentView()没有任何效果,这些仅为临时创建的视图实例,并未加入SwiftUI的视图渲染树。SwiftUI是状态驱动的视图框架,所有视图的切换、更新都必须通过状态变量的变化触发。
解决方案
方案1:根视图直接切换(适合登录后不需要返回登录页的场景)
仅需在body中通过loggedIn状态变量判断渲染对应视图即可,登录成功后修改loggedIn的值会自动触发视图刷新,修改后的代码如下:
import SwiftUI struct ContentView: View { @State var username : String = "" @State var password : String = "" @State var loggedIn : Bool = false @State var network = NetworkCall() var body: some View { // 根视图根据登录状态切换 if loggedIn { Dashboard() } else { ZStack { Color(red: 0.4627, green: 0.8392, blue: 1.0).ignoresSafeArea() VStack { Text("Login") .padding() TextField("Username", text: $username) .padding() SecureField("Password", text: $password) .padding() Button(action: { Task { do{ // 仅更新状态即可,视图会自动刷新 loggedIn = try await network.LoginFunction(userName: username, passWord: password) if loggedIn { print("Login Successful") } else { print("Login Unsuccessful") } }catch{ print("error", error) } } }) { Text("Sign in") .padding() .frame(minWidth: 100, maxWidth: 300, minHeight: 44) .foregroundColor(Color.white) .cornerRadius(30) .background(Color.blue) .cornerRadius(20) } } } } } }
方案2:导航栈跳转(适合需要支持返回登录页的场景)
如果需要保留导航层级,支持从Dashboard返回登录页,可以用NavigationStack的路径变量控制跳转:
import SwiftUI struct ContentView: View { @State var username : String = "" @State var password : String = "" @State var network = NetworkCall() // 导航路径控制跳转 @State private var navPath = NavigationPath() enum NavRoute: Hashable { case dashboard } var body: some View { NavigationStack(path: $navPath) { ZStack { Color(red: 0.4627, green: 0.8392, blue: 1.0).ignoresSafeArea() VStack { Text("Login") .padding() TextField("Username", text: $username) .padding() SecureField("Password", text: $password) .padding() Button(action: { Task { do{ let loginSuccess = try await network.LoginFunction(userName: username, passWord: password) if loginSuccess { print("Login Successful") // 往导航路径添加元素触发跳转 navPath.append(NavRoute.dashboard) } else { print("Login Unsuccessful") } }catch{ print("error", error) } } }) { Text("Sign in") .padding() .frame(minWidth: 100, maxWidth: 300, minHeight: 44) .foregroundColor(Color.white) .cornerRadius(30) .background(Color.blue) .cornerRadius(20) } } } // 配置导航目的地 .navigationDestination(for: NavRoute.self) { route in switch route { case .dashboard: Dashboard() } } } } }
额外优化建议
- 手动拼接JSON参数容易出错,建议通过字典转
Data的方式生成请求参数,避免用户名/密码包含特殊字符时导致请求格式错误。 - 若后续
NetworkCall需要新增状态通知视图,可让其遵守ObservableObject协议,并用@StateObject修饰变量替换当前的@State。
内容的提问来源于stack exchange,提问作者user3488019
相关产品推荐
相关产品推荐

