Search code examples
swiftuiviewmodelswiftui-navigation

I create the view in SwiftUI where i add textfield, and this view add in main SwiftUI and these is view model. I want change set if text in view Model


Current i did this code mention below for login activity there is custom text field which i created separately and load this is two time in main content which name is logintypeview. one is used for email and second use for password. and when user enter value in these field and click on login i want this in view model but it not happen when i get it in view model this is empty value even user enter values

This is my first view where I created the textfield and in this text field when user change text i want in view model which is linked with mainview

struct TextFieldView: View {
    var placeHolderName = "placeHolderName"
    var textFieldName = "textFieldName"
    var isPassword = false
    @State var enterText: String
    var body: some View {
        VStack(alignment: .leading){
            HStack{
                Text(textFieldName)
                    .customFont(AppFont.SemiBold16!)
                    .foregroundColor(Color(AppColor.primaryColor))
                Spacer()
            }
            .padding(.vertical,5)
            HStack{
                TextField("", text: $enterText)
                    .placeholder(when: enterText.isEmpty) {
                        Text(placeHolderName)
                            .foregroundColor(Color(AppColor.primaryColor))
                            .customFont(AppFont.Regular16!)
                    }
                    .foregroundColor(Color(AppColor.primaryColor))
                    .customFont(AppFont.Regular16!)
                    .hide(if: isPassword, withSpace: true)
                
                SecureField("", text: $enterText)
                    .placeholder(when: enterText.isEmpty) {
                        Text(placeHolderName)
                            .foregroundColor(Color(AppColor.primaryColor))
                            .customFont(AppFont.Regular16!)
                    }
                    .textContentType(.password)
                    .foregroundColor(Color(AppColor.primaryColor))
                    .customFont(AppFont.Regular16!)
                    .hide(if: !isPassword, withSpace: true)
                Spacer()
            }
            .frame(height: 40)
            .padding(.horizontal,20)
            .padding(.vertical,10)
            .overlay(
                RoundedRectangle(cornerRadius: 8)
                    .stroke(Color(AppColor.primaryColor), lineWidth: 1)
            )
        }
        .padding(.horizontal,20)
    }
}

struct LoginTypeView: View {
    @ObservedObject private var viewModel = LoginTypeViewModel()
    var body: some View {
        VStack{
            NavBarView(title: "Login")
            ScrollView {
                VStack() {
                    TextFieldView(placeHolderName: "Enter Email", textFieldName: "Email", enterText: $viewModel.emailInput)
                    TextFieldView(placeHolderName: "Enter Password", textFieldName: "Password", isPassword: true, enterText: $viewModel.passwordInput)
                }
            }
        }
    }
}

class LoginTypeViewModel: ObservableObject{
    @Published var emailInput = ""
    @Published var passwordInput = ""
    var loginSuccesfully: (() -\> ())?
    var loginFail: ((String) -\> ())?
}

i want change in viewmodel when user click on login button in main view and i want value in emailInput and passwordInput sending these value in API. One thing extra i need after successfull login i want to move to home screen which is build in UIKit how this is possitble.


Solution

  • It sounds like you want TextFieldView to update the state variable it is passed. This means passing it as a binding:

    • In TextFieldView, change the tag on enterText from @State to @Binding:
    @Binding var enterText: String
    
    • Also, the view model is being created in LoginTypeView, so it should be tagged as a @StateObject instead of as an @ObservedObject:
    @StateObject private var viewModel = LoginTypeViewModel()