簡體   English   中英

為什么點擊提交后文字會消失?

[英]Why does Text disappear when i click submit?

當我在 EditText 視圖中輸入以填寫所有必需的信息,然后單擊提交時。 我輸入的所有內容都消失了。 我希望保留此文本。 我猜我的@State對象有問題,但無法弄清楚是什么。

注冊視圖模型

class SignUpViewModel : ObservableObject {

    @Published
    var error: String? = nil

    @Published
    var goHome: Bool = false

    @Published
    var goToLogin: Bool = false

    func onGoToLoginClicked() {
        self.goToLogin = true
    }

    func signUp(firstName: String, lastName: String, email: String, birthday: String, phoneNumber: String, password: String, confirmPassword: String) {
        if (firstName.count < 3) {
            error = "Please enter first name"
            return
        }
        if (lastName.count < 3) {
            error = "Please enter last name"
            return
        }
        if (!email.isEmail()) {
            error = "Pleaes enter valid email"
            return
        }
        if (birthday.isEmpty) {
            error = "Pleae enter valid birthday"
            return
        }
        if (!phoneNumber.isDigits) {
            error = "Please enter valid phone number"
            return
        }
        if (password.count < 8) {
            error = "Please enter a password that is at least 8 characters long"
        }
        if (password != confirmPassword) {
            error = "Password do not match"
        }
        Auth.auth().createUser(withEmail: email, password: password, completion: { authResult, error in
            if authResult != nil {
                self.goHome = true
            } else {
                self.error = error?.localizedDescription
            }
        })
    }
}

注冊視圖

struct SignUpScreen: View {

    @State
    var firstName: String = ""
    @State
    var lastName: String = ""
    @State
    var birthday: String = ""
    @State
    var number: String = ""
    @State
    var email: String = ""
    @State
    var password: String = ""
    @State
    var confirmPassword: String = ""

    @EnvironmentObject
    var viewModel: SignUpViewModel


    var body: some View {
        ZStack {
            VStack {
                VClearBackground()
                Spacer()
            }
            ScrollView {
                VStack(alignment: .leading) {
                    Group {
                        PreHeaderText(header: "Get Started")
                            .alignmentGuide(.leading, computeValue: { d in
                                d[.leading]
                            })
                            .padding(EdgeInsets.init(top: 32, leading: 0, bottom: 0, trailing: 0))
                        HeaderText(header: "Create Account")
                        EditText(hint: "Huey", text: $firstName, label: "FIRST NAME", textContentType: UITextContentType.name)
                        EditText(hint: "Freeman", text: $lastName, label: "LAST NAME", textContentType: UITextContentType.name)
                        EditText(hint: "04-19-1994", text: $birthday, label: "BIRTHDAY")
                        EditText(hint: "(281) 456-7890)", text: $number, label: "MOBILE NUMBER", textContentType: UITextContentType.telephoneNumber, keyboardType: UIKeyboardType.phonePad)
                        EditText(hint: "email@exmaple.com", text: $email, label: "EMAIL", textContentType: UITextContentType.emailAddress)
                        EditText(hint: "********", text: $password, label: "PASSWORD", textContentType: UITextContentType.newPassword)
                        EditText(hint: "********", text: $confirmPassword, label: "CONFIRM PASSWORD", textContentType: UITextContentType.newPassword)
                    }
                    Group {
                        if self.viewModel.error != nil {
                            HStack {
                                Spacer()
                                Text(viewModel.error ?? "")
                                    .foregroundColor(ColorTheme.error.color)
                                Spacer()
                            }
                            .padding()
                        }
                        HStack {
                            Spacer()
                            VowerButton(text: "Submit") {
                                self.viewModel.signUp(firstName: self.firstName, lastName: self.lastName, email: self.email, birthday: self.birthday, phoneNumber: self.number, password: self.password, confirmPassword: self.confirmPassword)
                            }
                            Spacer()
                        }
                        .padding()

                        HStack {
                            Spacer()
                            NavigationLink(destination: LoginScreen(), isActive: $viewModel.goToLogin) {
                                CtaText(text: "Have an account?", cta: "Login") {
                                    self.viewModel.onGoToLoginClicked()
                                }
                            }
                            .padding()
                            Spacer()
                        }

                        Spacer()
                    }
                }
            }
            .padding(EdgeInsets.init(top: 16, leading: 16, bottom: 16, trailing: 16))
            .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .leading)
        }
        .background(LinearGradient(gradient: Gradient(colors: [.black, ColorTheme.brandPurple.color]), startPoint: .top, endPoint: .bottom))
        .edgesIgnoringSafeArea(.all)
    }
}

編輯文本視圖

struct EditText: View {

    var hint: String
    @Binding
    var text: String
    var label: String = ""
    var defaultValue =  ""
    var textContentType: UITextContentType? = .none
    var keyboardType: UIKeyboardType = .default

    private func initializeDefaultValue() {
        DispatchQueue.main.async {
            self.text = self.defaultValue
        }
    }

    var body: some View {
        initializeDefaultValue()
        return VStack(alignment: .leading) {
            Text(label).font(.system(size: 12)).bold()
                .foregroundColor(ColorTheme.text.color)
            HStack {
                TextField(hint, text: $text)
                .lineLimit(1)
                .textContentType(textContentType)
                .keyboardType(keyboardType)
                    .foregroundColor(ColorTheme.text.color)
            }
            Divider().background(Color(ColorTheme.brandBlue.value))
        }
        .padding(EdgeInsets.init(top: 12, leading: 0, bottom: 8, trailing: 0))
    }
}

預覽

問題代碼在SignUpScreen

@ObservedObject
var viewModel: SignUpViewModel = SignUpViewModel()

每當重新評估視圖時, SignUpViewModel創建一個新的SignUpViewModel

您可以在視圖之外創建視圖模型,並將其直接傳遞給構造函數,或者使用environmentObject()將其注入environmentObject()

要改用環境對象,請將上述聲明更改為:

@EnvironmentObject
var viewModel: SignUpViewModel

然后像這樣創建你的視圖:

var signUpViewModel = SignUpViewModel()

// ...

SignUpScreen()
    .environmentObject(signUpViewModel)

問題出在您的EditText視圖中。

struct EditText: View {

    var hint: String
    @Binding
    var text: String
    var label: String = ""
    var defaultValue =  ""
    var textContentType: UITextContentType? = .none
    var keyboardType: UIKeyboardType = .default

    private func initializeDefaultValue() {
        DispatchQueue.main.async {
            self.text = self.defaultValue
        }
    }

    var body: some View {
        initializeDefaultValue()
        return VStack(alignment: .leading) {
            Text(label).font(.system(size: 12)).bold()
                .foregroundColor(ColorTheme.text.color)
            HStack {
                TextField(hint, text: $text)
                .lineLimit(1)
                .textContentType(textContentType)
                .keyboardType(keyboardType)
                    .foregroundColor(ColorTheme.text.color)
            }
            Divider().background(Color(ColorTheme.brandBlue.value))
        }
        .padding(EdgeInsets.init(top: 12, leading: 0, bottom: 8, trailing: 0))
    }
}

具體來說,它在body屬性中。 這是一個計算屬性,每當重新計算視圖時,SwiftUI 都會獲取它。 在這種情況下,當SignUpScreen視圖的error屬性更改時會發生這種情況,因為所有子視圖都被重新計算。

重新計算此EditText視圖時,將調用initializeDefaultValue()函數(它是body屬性中的第一行)。 這將清除文本字段。

至於解決方案,我不確定為什么您實際上完全需要initializeDefaultValue函數。 它似乎最適合 ViewModel 或其他一些位置。


另外,我看到的其他一些東西:

func signUp(firstName: String, lastName: String, email: String, birthday: String, phoneNumber: String, password: String, confirmPassword: String) {
    if (firstName.count < 3) {
        error = "Please enter first name"
        return
    }
    if (lastName.count < 3) {
        error = "Please enter last name"
        return
    }
    if (!email.isEmail()) {
        error = "Pleaes enter valid email"
        return
    }
    if (birthday.isEmpty) {
        error = "Pleae enter valid birthday"
        return
    }
    if (!phoneNumber.isDigits) {
        error = "Please enter valid phone number"
        return
    }
    if (password.count < 8) {
        error = "Please enter a password that is at least 8 characters long"
    }
    if (password != confirmPassword) {
        error = "Password do not match"
    }
    Auth.auth().createUser(withEmail: email, password: password, completion: { authResult, error in
        if authResult != nil {
            self.goHome = true
        } else {
            self.error = error?.localizedDescription
        }
    })
}

除了最后兩個錯誤,這個函數在所有錯誤情況下都會提前返回——我認為這是一個錯誤。

if self.viewModel.error != nil {
    HStack {
        Spacer()
        Text(viewModel.error ?? "")
        .foregroundColor(ColorTheme.error.color)
        Spacer()
    }
    .padding()
}

SignUpScreen視圖的這一部分應該能夠簡化為:

if let err = self.viewModel.error {
    HStack {
        Spacer()
        Text(err)
        .foregroundColor(ColorTheme.error.color)
        Spacer()
    }
    .padding()
}

或者,如果在這種情況下不允許使用 if-let 語句:

if self.viewModel.error != nil {
    HStack {
        Spacer()
        Text(viewModel.error!)
        .foregroundColor(ColorTheme.error.color)
        Spacer()
    }
    .padding()
}

如您所知,錯誤是非nil


希望所有這些都有幫助!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM