英文:
How to show multiple alerts in the same view (struct) Xcode swiftUI Firebase
问题
我在Xcode中创建了一个更改密码视图,但其中的警报之一无法正常工作。
这是我的SwiftUI代码:
import SwiftUI
import FirebaseAuth
import FirebaseFirestore
extension String {
static func myNotEqual(lhs: String, rhs: String) -> Bool {
return lhs.range(of: rhs, options: .regularExpression) != nil
}
}
struct ResetPasswordView: View {
@Environment(\.presentationMode) var presentationMode
@Environment(\.dismiss) var dismiss
@Environment(\.colorScheme) var colorScheme
@State var emailID: String = ""
@State var ResetPassword: Bool = false
@State var OldPassword: String = ""
@State var NewPassword: String = ""
@State var showError: Bool = false
@State var errorMessage: String = ""
@State var isLoading: Bool = false
@State var showAlert = false
@State var showPasswordMismatchAlert: Bool = false
@State var showPasswordChangeSuccessAlert: Bool = false
var body: some View {
VStack(spacing: 10){
Text("Reset Your Password")
.font(.largeTitle.bold())
.hAlign(.leading)
.padding(.top, -220)
.padding(.leading, 14)
Text("Even If Your Password Is Wrong, There Will Be Sent a Link to Change Your Password To Your Current Email")
.font(.title3)
.hAlign(.leading)
.padding(.top, -190)
.padding(.leading, 15)
VStack{
TextField("Email", text: $emailID)
.disableAutocorrection(true)
.autocapitalization(.none)
.textContentType(.none)
.keyboardType(.emailAddress)
.border(1, .gray.opacity(0.5))
.hAlign(.center)
.padding(.leading, 1)
.padding(.all, 10)
.padding(.top, -20)
SecureTextField(text: $OldPassword)
.autocapitalization(.none)
.border(1, .gray.opacity(0.5))
.hAlign(.center)
.padding(.leading, 1)
.padding(.all, 10)
.padding(.top, -10)
Secure2TextField(text: $NewPassword)
.autocapitalization(.none)
.border(1, .gray.opacity(0.5))
.hAlign(.center)
.padding(.leading, 1)
.padding(.all, 10)
.padding(.top, -10)
.textContentType(.password)
Group{
Text("• 7 characters")
.padding(.leading, -83)
.foregroundColor(self.requirements[0] ? .green : .red)
Text("• 1 number")
.padding(.leading, -83)
.foregroundColor(self.requirements[1] ? .green : .red)
Text("• 1 special character(! @ # $ % ^ *)")
.padding(.leading, -0)
.foregroundColor(self.requirements[2] ? .green : .red)
}
.padding(.leading, -100)
Button("Change Password", action: changePassword)
.hAlign(.center)
.fillView(colorScheme == .light ? .black : .white)
.foregroundColor(colorScheme == .light ? .white : .black)
.padding(.leading, 1)
.padding(.all, 10)
.padding(.top, -10)
.disableWithOpacity(NewPassword == "" || emailID == "" || OldPassword == "" || requirements[0] == false || requirements[1] == false || requirements[2] == false)
Button("Back to Previous Page"){
dismiss()
}
.foregroundColor(colorScheme == .light ? .black : .white)
.font(.callout)
.fontWeight(.medium)
.tint(.black)
}
}
.alert(isPresented: $showPasswordMismatchAlert){
Alert(title: Text("Wrong Password or Email"), message: Text("Try Again"), dismissButton: .default(Text("OK")))
}
.alert(isPresented: $showPasswordChangeSuccessAlert){
Alert(title: Text("Done"), message: Text("All Changes Were Made"), dismissButton: .default(Text("OK")))
}
}
// 其他部分已省略...
//MARK: Displaying Errors VIA Alert
func setError(_ error: Error)async{
//MARK: UI Must be Updated on Main Thread
await MainActor.run(body: {
errorMessage = error.localizedDescription
showError.toggle()
isLoading = false
})
}
}
struct ResetPasswordView_Previews: PreviewProvider {
static var previews: some View {
ResetPasswordView()
}
}
英文:
He I have made an change password view in Xcode but the alerts one of them don't work.
here is my swiftUI code
import SwiftUI
import FirebaseAuth
import FirebaseFirestore
extension String {
static func myNotEqual(lhs: String, rhs: String) -> Bool {
return lhs.range(of: rhs, options: .regularExpression) != nil
}
}
struct ResetPasswordView: View {
@Environment(\.presentationMode) var presentationMode
@Environment(\.dismiss) var dismiss
@Environment(\.colorScheme) var colorScheme
@State var emailID: String = ""
@State var ResetPassword: Bool = false
@State var OldPassword: String = ""
@State var NewPassword: String = ""
@State var showError: Bool = false
@State var errorMessage: String = ""
@State var isLoading: Bool = false
@State var showAlert = false
@State var showPasswordMismatchAlert: Bool = false
@State var showPasswordChangeSuccessAlert: Bool = false
var body: some View {
VStack(spacing: 10){
Text("Reset Your Password")
.font(.largeTitle.bold())
.hAlign(.leading)
.padding(.top, -220)
.padding(.leading, 14)
Text("Even If Your Password Is Wrong, There Will Be Sent a Link to Change Your Password To Your Current Email")
.font(.title3)
.hAlign(.leading)
.padding(.top, -190)
.padding(.leading, 15)
VStack{
TextField("Email", text: $emailID)
.disableAutocorrection(true)
.autocapitalization(.none)
.textContentType(.none)
.keyboardType(.emailAddress)
.border(1, .gray.opacity(0.5))
.hAlign(.center)
.padding(.leading, 1)
.padding(.all, 10)
.padding(.top, -20)
SecureTextField(text: $OldPassword)
.autocapitalization(.none)
.border(1, .gray.opacity(0.5))
.hAlign(.center)
.padding(.leading, 1)
.padding(.all, 10)
.padding(.top, -10)
Secure2TextField(text: $NewPassword)
.autocapitalization(.none)
.border(1, .gray.opacity(0.5))
.hAlign(.center)
.padding(.leading, 1)
.padding(.all, 10)
.padding(.top, -10)
.textContentType(.password)
Group{
Text("• 7 characters")
.padding(.leading, -83)
.foregroundColor(self.requirements[0] ? .green : .red)
Text("• 1 number")
.padding(.leading, -83)
.foregroundColor(self.requirements[1] ? .green : .red)
Text("• 1 special character(! @ # $ % ^ *)")
.padding(.leading, -0)
.foregroundColor(self.requirements[2] ? .green : .red)
}
.padding(.leading, -100)
Button("Change Password", action: changePassword)
.hAlign(.center)
.fillView(colorScheme == .light ? .black : .white)
.foregroundColor(colorScheme == .light ? .white : .black)
.padding(.leading, 1)
.padding(.all, 10)
.padding(.top, -10)
.disableWithOpacity(NewPassword == "" || emailID == "" || OldPassword == "" || requirements[0] == false || requirements[1] == false || requirements[2] == false)
Button("Back to Previous Page"){
dismiss()
}
.foregroundColor(colorScheme == .light ? .black : .white)
.font(.callout)
.fontWeight(.medium)
.tint(.black)
}
}
.alert(isPresented: $showPasswordMismatchAlert){
Alert(title: Text("Wrong Password or Email"), message: Text("Try Again"), dismissButton: .default(Text("OK")))
}
.alert(isPresented: $showPasswordChangeSuccessAlert){
Alert(title: Text("Done"), message: Text("All Changes Were Made"), dismissButton: .default(Text("OK")))
}
}
func changePassword() {
Auth.auth().signIn(withEmail: emailID, password: OldPassword) { _, error in
if error != nil {
showPasswordMismatchAlert = true
}else{
Auth.auth().currentUser?.updatePassword(to: NewPassword)
showPasswordChangeSuccessAlert = true
let userUID = Auth.auth().currentUser?.uid
let databaseRef = Firestore.firestore().collection("Users").document(userUID!)
let updatePassword = NewPassword
databaseRef.setData(["passwordLog": updatePassword], merge: true) { (error) in
if let error = error {
print("Error updating document: \(error)")
} else {
print("Email updated successfully")
}
}
}
}
}
struct SecureTextField: View {
@State private var isSecureField: Bool = true
@Binding var text: String
var body: some View {
HStack{
if isSecureField {
SecureField ("Current Password", text: $text)
}else{
TextField("Current Password", text: $text)
}
}.overlay(alignment: .trailing) {
Image(systemName: isSecureField ? "eye.slash": "eye")
.onTapGesture {
isSecureField.toggle()
}
}
}
}
struct Secure2TextField: View {
@State private var isSecureField: Bool = true
@Binding var text: String
var body: some View {
HStack{
if isSecureField {
SecureField ("New Password", text: $text)
}else{
TextField("New Password", text: $text)
}
}.overlay(alignment: .trailing) {
Image(systemName: isSecureField ? "eye.slash": "eye")
.onTapGesture {
isSecureField.toggle()
}
}
}
}
private var requirements: Array<Bool> {
[
NewPassword.count >= 7, // Minimum Length
NewPassword != "[0-9]", // One Number
NewPassword != ".*[^A-Za-z0-9].*" // One Special Character
]
}
func VerifyPassword(){
showAlert = true
isLoading = true
Task{
do{
try await Auth.auth().sendPasswordReset(withEmail: emailID)
print("email sent")
try await Auth.auth().signIn(withEmail: emailID, password: OldPassword)
print("Pasword Worked")
changePassword()
}catch{
await setError(error)
}
}
}
//MARK: Displaying Errors VIA Alert
func setError(_ error: Error)async{
//MARK: UI Must be Updated on Main Thread
await MainActor.run(body: {
errorMessage = error.localizedDescription
showError.toggle()
isLoading = false
})
}
}
struct ResetPasswordView_Previews: PreviewProvider {
static var previews: some View {
ResetPasswordView()
}
}
I have tryd removing the $showPasswordChangeSuccessAlert alert and if I did that the $showPasswordMismatchAlert alert works and the other way around. so the problem I think is that I can't have two alerts at the same time in one view (struct) please help me
答案1
得分: 0
I solved the code, the problem was that I couldn't show two separate alerts in the same struct (view) so I made one alert that if is if showPasswordMismatchAlert = true he shows the mismatch alert and if is showPasswordChangeSuccessAlert = true he shows the success alert and I did the showPasswordChangeSuccessAlert = true thing in the error Handlemend of my function so if there was an error with "Auth.auth().signIn(withEmail: emailID, password: CurrentPassword)" he shows show showPasswordMismatchAlert = true and showAlert = true and if he doesn't have an error he shows showPasswordMismatchAlert = false showPasswordChangeSuccessAlert = true showAlert = true (why the false well if the user has had an error and now tries again and the showPasswordMismatchAlert wood still be true he wood show showPasswordMismatchAlert) the error Handlemend shit of my function is
func changePassword() {
Auth.auth().signIn(withEmail: emailID, password: CurrentPassword) { _, error in
if error != nil {
Auth.auth().sendPasswordReset(withEmail: emailID)
showPasswordMismatchAlert = true
showAlert = true
} else {
Auth.auth().sendPasswordReset(withEmail: emailID)
Auth.auth().currentUser?.updatePassword(to: NewPassword)
showPasswordMismatchAlert = false
showPasswordChangeSuccessAlert = true
showAlert = true
let userUID = Auth.auth().currentUser?.uid
let databaseRef = Firestore.firestore().collection("Users").document(userUID!)
let updatePassword = ["passwordLog": NewPassword]
databaseRef.updateData(updatePassword)
let updateEmailLog = ["userEmail": emailID]
databaseRef.updateData(updateEmailLog)
}
}
}
import SwiftUI
import FirebaseAuth
import FirebaseFirestore
extension String {
static func myNotEqual(lhs: String, rhs: String) -> Bool {
return lhs.range(of: rhs, options: .regularExpression) != nil
}
}
struct ResetPasswordView: View {
@Environment(\.presentationMode) var presentationMode
@Environment(\.dismiss) var dismiss
@Environment(\.colorScheme) var colorScheme
@State var emailID: String = ""
@State var ResetPassword: Bool = false
@State var CurrentPassword: String = ""
@State var NewPassword: String = ""
@State var showError: Bool = false
@State var errorMessage: String = ""
@State var isLoading: Bool = false
@State var showAlert = false
@State var showPasswordMismatchAlert: Bool = false
@State var showPasswordChangeSuccessAlert: Bool = false
var body: some View {
VStack(spacing: 10){
Text("Reset Your Password")
.font(.largeTitle.bold())
.hAlign(.leading)
.padding(.top, -260)
.padding(.leading, 14)
Text("If You Don't Know Your Password Don't Worry,\nThere Will Be Sent a Reset Link to Your Email, Regardless of if You Put in The Right Password")
.hAlign(.leading)
.padding(.top, -230)
.padding(.leading, 14)
VStack{
TextField("Email", text: $emailID)
.disableAutocorrection(true)
.autocapitalization(.none)
.textContentType(.none)
.keyboardType(.emailAddress)
.border(1, .gray.opacity(0.5))
.hAlign(.center)
.padding(.leading, 1)
.padding(.all, 10)
.padding(.top, -100)
SecureTextField(text: $CurrentPassword)
.autocapitalization(.none)
.border(1, .gray.opacity(0.5))
.hAlign(.center)
.padding(.leading, 1)
.padding(.all, 10)
.padding(.top, -60)
Secure2TextField(text: $NewPassword)
.autocapitalization(.none)
.border(1, .gray.opacity(0.5))
.hAlign(.center)
.padding(.leading, 1)
.padding(.all, 10)
.padding(.top, -20)
.textContentType(.password)
Group{
Text("• 7 characters")
.padding(.leading, -83)
.foregroundColor(self.requirements[0] ? .green : .red)
Text("• 1 number")
.padding(.leading, -83)
.foregroundColor(self.requirements[1] ? .green : .red)
Text("• 1 special character(! @ # $ % ^ )")
.padding(.leading, -0)
.foregroundColor(self.requirements[2] ? .green : .red)
}
.padding(.leading, -100)
Button("Change Password", action: changePassword)
.hAlign(.center)
.fillView(colorScheme == .light ? .black : .white)
.foregroundColor(colorScheme == .light ? .white : .black)
.padding(.leading, 1)
.padding(.all, 10)
.padding(.top, -10)
.disableWithOpacity(NewPassword == "" || emailID == "" || CurrentPassword == "" || requirements[0] == false || requirements[1] == false || requirements[2] == false)
Button("Back to Previous Page"){
dismiss()
}
.foregroundColor(colorScheme == .light ? .black : .white)
.font(.callout)
.fontWeight(.medium)
.tint(.black)
}
}
.alert(isPresented: $showAlert) {
if showPasswordMismatchAlert {
return Alert(title: Text("Wrong Password or Email"), message: Text("Try Again"), dismissButton: .default(Text("OK")))
} else if showPasswordChangeSuccessAlert {
return Alert(title: Text("Your Password is Changed"), message: Text("There is an email sent to your current email if you want to change it back within the next hour"), dismissButton: .default(Text("OK")))
} else {
return Alert(title: Text("Not Right"), message: Text("something is wrong contact the developer at ziya@ziyaxservers.nl"), dismissButton: .default(Text("OK")))
}
}
}
func changePassword() {
Auth.auth().signIn(withEmail: emailID, password: CurrentPassword) { _, error in
if error != nil {
Auth.auth().sendPasswordReset(withEmail: emailID)
showPasswordMismatchAlert = true
showAlert = true
} else {
Auth.auth().sendPasswordReset(withEmail: emailID)
Auth.auth().currentUser?.updatePassword(to: NewPassword)
showPasswordMismatchAlert = false
showPasswordChangeSuccessAlert = true
showAlert = true
let userUID = Auth.auth().currentUser?.uid
let databaseRef = Firestore.firestore().collection("Users").document(userUID!)
let updatePassword = ["passwordLog": NewPassword]
databaseRef.updateData(updatePassword)
let updateEmailLog =
<details>
<summary>英文:</summary>
I solved the code,
the problem was that I couldn't show two separate alerts in the same struct (view) so I made one alert that if is if showPasswordMismatchAlert = true he shows the mismatch alert and if is showPasswordChangeSuccessAlert = true he shows the success alert and I did the showPasswordChangeSuccessAlert = true thing in the error Handlemend of my function so if there was an error with "Auth.auth().signIn(withEmail: emailID, password: CurrentPassword)" he shows show showPasswordMismatchAlert = true and showAlert = true and if he doesn't have an error he shows showPasswordMismatchAlert = false showPasswordChangeSuccessAlert = true showAlert = true (why the false well if the user has had an error and now tries again and the showPasswordMismatchAlert wood still be true he wood show showPasswordMismatchAlert) the error Handlemend shit of my function is
func changePassword() {
Auth.auth().signIn(withEmail: emailID, password: CurrentPassword) { _, error in
if error != nil {
Auth.auth().sendPasswordReset(withEmail: emailID)
showPasswordMismatchAlert = true
showAlert = true
} else {
Auth.auth().sendPasswordReset(withEmail: emailID)
Auth.auth().currentUser?.updatePassword(to: NewPassword)
showPasswordMismatchAlert = false
showPasswordChangeSuccessAlert = true
showAlert = true
let userUID = Auth.auth().currentUser?.uid
let databaseRef = Firestore.firestore().collection("Users").document(userUID!)
let updatePassword = ["passwordLog": NewPassword]
databaseRef.updateData(updatePassword)
let updateEmailLog = ["userEmail": emailID]
databaseRef.updateData(updateEmailLog)
}
}
}
import SwiftUI
import FirebaseAuth
import FirebaseFirestore
extension String {
static func myNotEqual(lhs: String, rhs: String) -> Bool {
return lhs.range(of: rhs, options: .regularExpression) != nil
}
}
struct ResetPasswordView: View {
@Environment(.presentationMode) var presentationMode
@Environment(.dismiss) var dismiss
@Environment(.colorScheme) var colorScheme
@State var emailID: String = ""
@State var ResetPassword: Bool = false
@State var CurrentPassword: String = ""
@State var NewPassword: String = ""
@State var showError: Bool = false
@State var errorMessage: String = ""
@State var isLoading: Bool = false
@State var showAlert = false
@State var showPasswordMismatchAlert: Bool = false
@State var showPasswordChangeSuccessAlert: Bool = false
var body: some View {
VStack(spacing: 10){
Text("Reset Your Password")
.font(.largeTitle.bold())
.hAlign(.leading)
.padding(.top, -260)
.padding(.leading, 14)
Text("If You Don't Know Your Password Don't Worry,\nThere Will Be Sent a Reset Link to Your Email, Regardless of if You Put in The Right Password")
.hAlign(.leading)
.padding(.top, -230)
.padding(.leading, 14)
VStack{
TextField("Email", text: $emailID)
.disableAutocorrection(true)
.autocapitalization(.none)
.textContentType(.none)
.keyboardType(.emailAddress)
.border(1, .gray.opacity(0.5))
.hAlign(.center)
.padding(.leading, 1)
.padding(.all, 10)
.padding(.top, -100)
SecureTextField(text: $CurrentPassword)
.autocapitalization(.none)
.border(1, .gray.opacity(0.5))
.hAlign(.center)
.padding(.leading, 1)
.padding(.all, 10)
.padding(.top, -60)
Secure2TextField(text: $NewPassword)
.autocapitalization(.none)
.border(1, .gray.opacity(0.5))
.hAlign(.center)
.padding(.leading, 1)
.padding(.all, 10)
.padding(.top, -20)
.textContentType(.password)
Group{
Text("• 7 characters")
.padding(.leading, -83)
.foregroundColor(self.requirements[0] ? .green : .red)
Text("• 1 number")
.padding(.leading, -83)
.foregroundColor(self.requirements[1] ? .green : .red)
Text("• 1 special character(! @ # $ % ^ *)")
.padding(.leading, -0)
.foregroundColor(self.requirements[2] ? .green : .red)
}
.padding(.leading, -100)
Button("Change Password", action: changePassword)
.hAlign(.center)
.fillView(colorScheme == .light ? .black : .white)
.foregroundColor(colorScheme == .light ? .white : .black)
.padding(.leading, 1)
.padding(.all, 10)
.padding(.top, -10)
.disableWithOpacity(NewPassword == "" || emailID == "" || CurrentPassword == "" || requirements[0] == false || requirements[1] == false || requirements[2] == false)
Button("Back to Previous Page"){
dismiss()
}
.foregroundColor(colorScheme == .light ? .black : .white)
.font(.callout)
.fontWeight(.medium)
.tint(.black)
}
}
.alert(isPresented: $showAlert) {
if showPasswordMismatchAlert {
return Alert(title: Text("Wrong Password or Email"), message: Text("Try Again"), dismissButton: .default(Text("OK")))
} else if showPasswordChangeSuccessAlert {
return Alert(title: Text("Your Password is Changed"), message: Text("There is an email sent to your current email if you want to change it back within the next hour"), dismissButton: .default(Text("OK")))
} else {
return Alert(title: Text("Not Right"), message: Text("something is wrong contact the develeper at ziya@ziyaxservers.nl"), dismissButton: .default(Text("OK")))
}
}
}
func changePassword() {
Auth.auth().signIn(withEmail: emailID, password: CurrentPassword) { _, error in
if error != nil {
Auth.auth().sendPasswordReset(withEmail: emailID)
showPasswordMismatchAlert = true
showAlert = true
} else {
Auth.auth().sendPasswordReset(withEmail: emailID)
Auth.auth().currentUser?.updatePassword(to: NewPassword)
showPasswordMismatchAlert = false
showPasswordChangeSuccessAlert = true
showAlert = true
let userUID = Auth.auth().currentUser?.uid
let databaseRef = Firestore.firestore().collection("Users").document(userUID!)
let updatePassword = ["passwordLog": NewPassword]
databaseRef.updateData(updatePassword)
let updateEmailLog = ["userEmail": emailID]
databaseRef.updateData(updateEmailLog)
}
}
}
struct SecureTextField: View {
@State private var isSecureField: Bool = true
@Binding var text: String
var body: some View {
HStack{
if isSecureField {
SecureField ("Current Password", text: $text)
}else{
TextField("Current Password", text: $text)
}
}.overlay(alignment: .trailing) {
Image(systemName: isSecureField ? "eye.slash": "eye")
.onTapGesture {
isSecureField.toggle()
}
}
}
}
struct Secure2TextField: View {
@State private var isSecureField: Bool = true
@Binding var text: String
var body: some View {
HStack{
if isSecureField {
SecureField ("New Password", text: $text)
}else{
TextField("New Password", text: $text)
}
}.overlay(alignment: .trailing) {
Image(systemName: isSecureField ? "eye.slash": "eye")
.onTapGesture {
isSecureField.toggle()
}
}
}
}
private var requirements: Array<Bool> {
[
NewPassword.count >= 7, // Minimum Length
NewPassword != "[0-9]", // One Number
NewPassword != ".*[^A-Za-z0-9].*" // One Special Character
]
}
}
struct ResetPasswordView_Previews: PreviewProvider {
static var previews: some View {
ResetPasswordView()
}
}
</details>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论