SwiftUi @ enum类型的状态变量为nil



我有四个视图:

LoginView()
SignInWithEmailView()
SignUpView()
ForgotPasswordView()

LoginView:

struct LoginView: View {

enum Action {
case signUp, resetPW
}
@State private var showSheet = false
@State private var action: Action?
init() {
print(self.action) //prints nil
}

var body: some View {
VStack {
SignInWithEmailView(showSheet: $showSheet, action: $action)
SignInWithAppleView()
.frame(width: 200, height: 50)
Spacer()
}
.sheet(isPresented: $showSheet) {
if self.action == .signUp {
SignUpView()
} else {
ForgotPasswordView()
}
}
}
}

SignInWithEmailView:

struct SignInWithEmailView: View {
@EnvironmentObject var userInfo: UserInfo
@State var user: UserViewModel = UserViewModel()
@Binding var showSheet: Bool
@Binding var action: LoginView.Action?

@State private var showAlert = false
@State private var authError: EmailAuthError?

var body: some View {
VStack {
CustomTextField(secureInput: false, titleKey: "Email Address",
fieldText: self.$user.email)
.autocapitalization(.none)
.keyboardType(.emailAddress)
CustomTextField(secureInput: true, titleKey: "Password", fieldText: $user.password)
HStack {
Spacer()
Button(action: {
self.showSheet = true
self.action = .resetPW
}) {
Text("Forgot Password")
}
}.padding(.bottom)
VStack(spacing: 10) {
FormButton(buttonText: "Login", buttonAction: {
FBAuth.authenticate(withEmail: self.user.email,
password: self.user.password) { (result) in
switch result {
case .failure(let error):
self.authError = error
self.showAlert = true
case .success( _):
print("Signed in")
}
}
})
.opacity(user.isLogInComplete ? 1 : 0.5)
.disabled(!user.isLogInComplete)

FormButton(buttonText: "Sign UP", buttonAction: {
self.showSheet = true
self.action = .signUp
})
}
.alert(isPresented: $showAlert) {
Alert(title: Text("Login Error"), message: Text(self.authError?.localizedDescription ?? "Unknown error"), dismissButton: .default(Text("OK")) {
if self.authError == .incorrectPassword {
self.user.password = ""
}else {
self.user.email = ""
self.user.password = ""
}
})
}
}
.padding(.top, 100)
.frame(width: 300)
.textFieldStyle(RoundedBorderTextFieldStyle())

}
}

SignUpView:

struct SignUpView: View {
@EnvironmentObject var userInfo: UserInfo
@State var user: UserViewModel = UserViewModel()
@Environment(.presentationMode) var presentationMode

@State private var showError = false
@State private var errorString = ""
var body: some View {
NavigationView {
VStack {
Group {
AvatarSelection()
VStack(alignment: .leading) {
CustomTextField(secureInput: false, titleKey: "Full Name", fieldText: self.$user.fullname)
if !user.validNameText.isEmpty {
Text(user.validNameText).font(.caption).foregroundColor(.red)
}
}
VStack(alignment: .leading) {
CustomTextField(secureInput: false, titleKey: "Email Address", fieldText: self.$user.email).autocapitalization(.none).keyboardType(.emailAddress)
if !user.validEmailAddressText.isEmpty {
Text(user.validEmailAddressText).font(.caption).foregroundColor(.red)
}
}
VStack(alignment: .leading) {
CustomTextField(secureInput: true, titleKey: "Password", fieldText: self.$user.password)
if !user.validPasswordText.isEmpty {
Text(user.validPasswordText).font(.caption).foregroundColor(.red)
}
}
VStack(alignment: .leading) {
CustomTextField(secureInput: true, titleKey: "Confirm Password", fieldText: self.$user.confirmPassword)
if !user.passwordsMatch(_confirmPW: user.confirmPassword) {
Text(user.validConfirmPasswordText).font(.caption).foregroundColor(.red)
}
}
}.frame(width: 300)
.textFieldStyle(RoundedBorderTextFieldStyle())
VStack(spacing: 20 ) {
FormButton(buttonText: "Sign Up", buttonAction: {
// Signup
FBAuth.createUser(withEmail: self.user.email,
name: self.user.fullname,
password: self.user.password) { (result) in
switch result {
case .failure(let error):
self.errorString = error.localizedDescription
self.showError = true
case .success( _):
print("Account Creation Successful")
}
}

})
.opacity(user.isSignInComplete ? 1 : 0.5)
.disabled(!user.isSignInComplete)

Spacer()
}.padding()
}.padding(.top)
.alert(isPresented: $showError) {
Alert(title: Text("Error Creating an Account"), message: Text(self.errorString), dismissButton: .default(Text("OK")))
}
.navigationBarTitle("Sign Up", displayMode: .inline)
.navigationBarItems(trailing: Button("Dismiss") {
self.presentationMode.wrappedValue.dismiss()
})
}
}
}

ForgotPasswordView:

struct ForgotPasswordView: View {
@State var user: UserViewModel = UserViewModel()
@Environment(.presentationMode) var presentationMode
@State private var showAlert = false
@State private var errString: String?

var body: some View {
NavigationView {
VStack {
TextField("Enter email address", text: $user.email).autocapitalization(.none).keyboardType(.emailAddress)
FormButton(buttonText: "Submit", buttonAction: {
FBAuth.resetPassword(email: self.user.email) { (result) in
switch result {
case .failure(let error):
self.errString = error.localizedDescription
case .success( _):
break
}
self.showAlert = true
}
})

.disabled(!user.isEmailValid(_email: user.email))
Spacer()
}.padding(.top)
.frame(width: 300)
.textFieldStyle(RoundedBorderTextFieldStyle())
.navigationBarTitle("Request a password reset", displayMode: .inline)
.navigationBarItems(trailing: Button("Dismiss") {
self.presentationMode.wrappedValue.dismiss()
})
.alert(isPresented: $showAlert) {
Alert(title: Text("Password Reset"), message: Text(self.errString ?? "Success, Password reset email was sent, Check your email"), dismissButton: .default(Text("OK")) {
self.presentationMode.wrappedValue.dismiss()
})
}
}
}
}

:

在loginView中,当我第一次点击注册按钮时,表单打开ForgotPasswordView()//这是错误的

当我关闭工作表并点击ForgotPassword,工作表打开ForgotPassword//这是正确的

当我关闭工作表并再次点击注册按钮时,工作表打开SignUpView//右

如何从第一次尝试打开SignupView ?

我解决了这个谜,在LoginView:

i changed this:

SignInWithEmailView(showSheet: $showSheet, action: $action)

:

SignInWithEmailView(showSheet: $showSheet, action: self.action == nil ? $action : $action)

,它就像一个魅力;)

在apple开发论坛上找到的

iOS 14的Swift UI不给@State property分配新对象- https://developer.apple.com/forums/thread/652080

还包含了解决这个苹果错误的合法方法:

让Action确认一些原始值,例如String,然后将其添加到视图中:

Text("(action?.rawValue ?? "")"
.hidden()

相关内容

  • 没有找到相关文章

最新更新