【发布时间】:2021-02-03 00:00:45
【问题描述】:
我在名为 authState 的环境对象中使用 isLoading Bool。
import Foundation
import FirebaseAuth
import Combine
class AuthState: ObservableObject {
enum AuthStateMode {
case unregistered
case signedInAnonymously
case signedInWithEmail
}
@Published var user: User?
@Published var authStateMode: AuthStateMode = .unregistered
@Published var error: AuthError?
@Published var isLoading: Bool = false
private var cancellables = Set<AnyCancellable>()
let authService = AuthService()
init() {
authService.authStateSubject.assign(to: &$user)
$user.map { user -> AuthStateMode in
if let user = user {
if user.email != nil { return .signedInWithEmail }
else if user.uid != "" { return .signedInAnonymously }
else { return .unregistered }
} else { return .unregistered }
}.assign(to: &$authStateMode)
}
func signIn(email: String, password: String) {
self.isLoading = true
authService.signIn(email: email, password: password)
.sink { completion in
self.isLoading = false
switch completion {
case let .failure(error):
return self.error = error
case .finished: return print("authState.signIn finished")
}
} receiveValue: { _ in }
.store(in: &cancellables)
}
func signInAnonymously() {
isLoading = true
authService.signInAnonymously()
.sink { completion in
self.isLoading = false
switch completion {
case let .failure(error):
return self.error = error
case .finished: return
}
} receiveValue: { user in
self.user = user
}.store(in: &cancellables)
}
func linkAccount(email: String, password: String) {
isLoading = true
authService.linkAccount(email: email, password: password)
.sink { completion in
self.isLoading = false
switch completion {
case let .failure(error):
return self.error = error
case .finished:
return print("linkAccount finished")
}
} receiveValue: { user in
self.user = user
}
.store(in: &cancellables)
}
}
我有一个使用 authState.isLoading Bool 的父视图。
import SwiftUI
import Combine
struct SelectUserTypeView: View {
@EnvironmentObject var authState: AuthState
var body: some View {
NavigationView {
VStack {
Spacer()
if authState.isLoading == true {
ProgressView()
} else if authState.authStateMode == .unregistered {
Button { authState.signInAnonymously() }
label:{ Text("Connect") }
} else {
NavigationLink(
destination: GuestPreviewView(),
label: { Text("Join as Guest") })
Spacer()
NavigationLink(
destination: SignInUpView(viewModel: .init(mode: .signUp)),
label: { Text("Host a Session") })
}
Spacer()
NavigationLink(destination: RecordingsView(),
label: { Text("Browse Recordings") })
Spacer()
.navigationBarTitle(Text("Welcome to Fullres"), displayMode: .inline)
.onAppear(perform: authState.signInAnonymously)
}
}
}
}
我有一个也使用 authState.isLoading Bool 的子视图。
import SwiftUI
import Combine
struct SignInUpView: View {
@EnvironmentObject var authState: AuthState
@StateObject var viewModel: SignInUpViewModel
var body: some View {
ZStack {
if authState.isLoading {
ProgressView()
} else if authState.authStateMode == .signedInWithEmail {
HostPreviewView()
} else {
VStack {
Spacer()
Text(viewModel.heading)
.font(.title)
.bold()
.padding()
if let error = authState.error { Text("\(error.localizedDescription)") }
TextField("Email", text: $viewModel.email)
.autocapitalization(/*@START_MENU_TOKEN@*/.none/*@END_MENU_TOKEN@*/)
.disableAutocorrection(true)
.padding()
SecureField("Password", text: $viewModel.password)
.autocapitalization(/*@START_MENU_TOKEN@*/.none/*@END_MENU_TOKEN@*/)
.disableAutocorrection(true)
.padding()
Button(viewModel.signInUpBtnLbl) {signInUpBtnAction()}
.font(.title2)
.padding()
Spacer()
Button(viewModel.signInUpModeBtnLbl) {
viewModel.mode.toggle()
}
.padding()
Spacer()
}
}
}
}
func signInUpBtnAction() {
switch viewModel.mode {
case .signIn: authState.signIn(email: viewModel.email, password: viewModel.password)
case .signUp: authState.linkAccount(email: viewModel.email, password: viewModel.password)
}
}
}
似乎每当 isLoading Bool 在子视图上切换为 true 时,UI 都会呈现父视图。
有人能说明如何最好地解决这个问题吗?
【问题讨论】:
-
您没有提供足够的代码来诊断这个问题
-
我很抱歉。我仍然知道要分享多少/很少。谢谢!