存在以下问题:必须为应用程序创建一个授权窗口,这是我发现的以下实现的最符合逻辑的解决方案(我不得不这样做,因为mainView有一个tabView,如果它在navigationView中的行为不正确)
struct ContentView: View {
@EnvironmentObject var vm: AppSettings
var body: some View {
if vm.isLogin {
MainView()
} else {
LoginView()
}
}AppSettings看起来是这样的:
struct MyApp: App {
@StateObject var appSetting = AppSettings()
var body: some Scene {
WindowGroup {
ContentView()
.environmentObject(appSetting)
}
}
}
class AppSettings: ObservableObject {
@Published var isLogin = false
}默认情况下,将向用户显示如下所示的授权窗口:
struct LoginView: View {
@StateObject var vm = LoginViewModel()
var body: some View {
NavigationView {
VStack {
TextField("Email", text: $vm.login)
TextField("Password", text: $vm.password)
Button {
vm.auth()
} label: {
Text("SignIn")
}
}
}
}
}最后,loginViewModel看起来是这样的:
class LoginViewModel: ObservableObject {
@Published var login = ""
@Published var password = ""
//@Published var appSettings = AppSettings() -- error on the first screenshot
//or
//@EnvironmentObject var appSettings: AppSettings -- error on the second screenshot
func auth() {
UserAPI().Auth(req: LoginRequest(email: login, password: password)) { response, error in
if let err = error {
// Error Processing
} else if let response = response {
Defaults.accessToken = response.tokens.accessToken
Defaults.refreshToken = response.tokens.refreshToken
self.appSettings.isLogin = true
}
}
}
}1错误- 访问StateObject的对象而不安装在视图上。这将每次创建一个新实例。
2错误- ),因为AppSettings作为此视图的祖先可能会丢失
我请求帮助,我只是找不到一个方式来进行两个observableObject的交互。为了实现这样的功能,我不得不将所有的逻辑插入到按钮的操作中。
除了此功能外,还计划在各种情况下将isLogin变量更改为false或使用其他环境变量轻松实现其他函数,从而实现帐户的退出。
为了简单地解释情况,这个例子被刻意简化了。
发布于 2022-10-24 11:24:15
我认为只在顶层使用LoginViewModel是解决这一问题的最简单方法。但是,如果要同时保持这两种情况,可以使用.onChanged修饰符来同步它们。
class LoginViewModel: ObservableObject {
@Published var login = ""
@Published var password = ""
@Published var isLogin = false
func auth() {
UserAPI().Auth(req: LoginRequest(email: login, password: password)) { response, error in
if let err = error {
// Error Processing
} else if let response = response {
Defaults.accessToken = response.tokens.accessToken
Defaults.refreshToken = response.tokens.refreshToken
isLogin = true
}
}
}
}
struct LoginView: View {
@StateObject var vm = LoginViewModel()
// grab the AppSettings from the environment
@EnvironmentObject var appSetting: AppSettings
var body: some View {
NavigationView {
VStack {
TextField("Email", text: $vm.login)
TextField("Password", text: $vm.password)
Button {
vm.auth()
} label: {
Text("SignIn")
}
// synchronise the viewmodels here
.onChange(of: vm.isLogin) { newValue in
appSetting.isLogin = newValue
}
}
}
}
}https://stackoverflow.com/questions/74177998
复制相似问题