Почему текст исчезает, когда я нажимаю кнопку отправить? - PullRequest
0 голосов
/ 28 февраля 2020

Когда я набираю в своем окне EditText, чтобы заполнить всю необходимую информацию, а затем нажмите кнопку Отправить. Все, что я напечатал, исчезает. Я хочу, чтобы этот текст остался. Я предполагаю, что что-то не так с моими @State объектами, но не могу понять, что.

SignUpViewModel

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
            }
        })
    }
}

SignUp View

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)
    }
}

EditText View

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))
    }
}

Preview

Ответы [ 2 ]

1 голос
/ 02 марта 2020

Проблема в вашем 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 всякий раз, когда представление пересчитывается. В этом случае это происходит при изменении свойства error представления SignUpScreen, поскольку все подпредставления пересчитываются.

Когда это представление 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()
}

или, если если- операторы let в этом случае недопустимы:

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

, поскольку вы знаете, что ошибка не является nil.


Надеюсь, все это поможет!

1 голос
/ 29 февраля 2020

Код проблемы: SignUpScreen:

@ObservedObject
var viewModel: SignUpViewModel = SignUpViewModel()

При повторной оценке вида создается новый SignUpViewModel.

Вы можете создать модель вида снаружи представление и либо передать его непосредственно конструктору, либо внедрить его в среду, используя environmentObject().

Чтобы использовать вместо этого объект среды, измените приведенное выше объявление на:

@EnvironmentObject
var viewModel: SignUpViewModel

А затем создайте свой вид так:

var signUpViewModel = SignUpViewModel()

// ...

SignUpScreen()
    .environmentObject(signUpViewModel)
...