Isaiah Thompson
Isaiah Thompson

Reputation: 85

State Variable From A Textfield With Input Is Returning Null

I have a custom struct which contains a Textfield, and a state variable associated with the textfield. Every time I just try to validate the Textfield, the state variable is null, even if there is input inside the Textfield. Is there some thing that I am missing?

This is in my Signup class:

//
//  Signup.swift
//  Lazuli Social
//
//  Created by user207789 on 12/28/21.
//

import SwiftUI

struct Signup: View
{
       
    //If Everything Is Valid
    @State var isValid: Bool = false;

    init()
    {
        
       
    }
    
    
    var body: some View
    {
        NavigationView
        {
            GeometryReader
            {
                metrics in
            
                VStack (alignment: .center)
                {
      
                   //First Name
                    var first:EnhancedTextField = 
                    EnhancedTextField(hintIn:"First name", widthIn: 
                    metrics.size.width, 
                    heightIn:metrics.size.height,typeIn:0);
                                     
                    //Displays First
                    first;
                    
                    Button(
                            action:
                            {  
                                
                                if(first.checkErrors()==true)//THE INPUT IS BLANK HERE, EVEN WITH INPUT TEXT
                                {
                                    //There Was Some Error
                                    isValid=false;
                                }
                                else
                                {
                                    //No Error
                                    isValid=true;
                                }
                            }
                            ,label:
                                    {    
                                       
                                     Text("")
                                       
                                    })
                    //Next Button
                    NavigationLink(destination: AccountInfo(),isActive: 
                    .constant(isValid==true))
                    {
    
                   
                    }
                    .navigationBarHidden(true)
                    .navigationBarTitle("")
                    .disabled(isValid==false)
                }
            }
            
    }
        .navigationBarHidden(true)
        .navigationBarTitle("")}
}



Here is my custom struct, which contains the Textfield:

//
//  EnhancedTextField.swift
//  Lazuli Social
//
//  Created by user207789 on 12/29/21.
//

import SwiftUI


     
    
struct EnhancedTextField: View
{
    @State var hint: String;
    
    //First Name Input
    @State public var text: String = "" //THIS IS NULL, EVEN WHEN THERE IS INPUT
    
    //If First Name Focus Is Changed
    @FocusState public var isFocused: Bool
    

    //StringDetector Class
    var detector: StringDetector
    
    
    public func checkErrors() -> Bool
    {
        if(type==0)
        {
            let result = checkErrorsFirstName();
            return result;
        }
        else
        {
            return true;
        }
    }
    
    public func checkErrorsFirstName() -> Bool
    {
        //StrignDetector Result
       let result = detector.checkErrorsFirstName(first:self.text);//THIS IS WHERE I'M TRYING TO PASS THE INPUT OF TEXTFIELD TO AN INTERNAL CLASS FOR STRING VALIDATION, HOWEVER IT IS ALWAYS EMPTYM EVEN WITH INPUT
           
           //Error Text
           errorText=result.1;
           
           //Bordrer Color
           borderColor=result.2;
           
           //Icon String
           iconName=result.3;
           
           //Icon Color
           iconColor=result.4;
        
        //There Is An Validation Error
        if(result.0==true)
        {
            return true;
        }
        else
        {
            return false;
        }
        
            
    }
    
   
    var body: some View
    {
        
            VStack (alignment: .center)
            {
                
               //First Name Input
               TextField(hint, text: $text)
              .padding(.bottom, height*Alpha.tAlpha)
              .padding(.top, height*Alpha.tAlpha)
              .frame(maxWidth: .infinity, alignment: .center)
              .focused($isFocused)
              .textInputAutocapitalization(.never)
              .disableAutocorrection(true)
              .onChange(of:isFocused)
              {
                  newValue in
                  
                  if (newValue==false)
                  {
                      //Check Validation Errors
                      checkErrors();
                      
                  }
                  .padding(.horizontal, width*0.10)
              
                      
                }
               

        }
    
}

Thanks,

Isaiah Thompson

Upvotes: 0

Views: 356

Answers (1)

jnpdx
jnpdx

Reputation: 52565

Here's a very simplified version of your code showing state owned by the parent. Validity just tests whether the text is empty or not (just for demo purposes).

func checkErrors(input: String) -> Bool {
    return !input.isEmpty
}

struct Signup: View
{
    @State private var text : String = ""
    @State private var isValid : Bool = false
    
    var body: some View
    {
     
        EnhancedTextField(hint: "Hint", text: $text)
            .border(isValid ? .clear : .red)
            
        Button(action: {
            isValid = checkErrors(input: text)
        }) {
            Text("Test")
        }
    }
}

struct EnhancedTextField: View
{
    @State var hint: String
    @Binding var text: String
    @FocusState private var isFocused: Bool
    @State private var hasErrors = false
    
    var body: some View
    {
        
            VStack (alignment: .center)
            {
                
               //First Name Input
               TextField(hint, text: $text)
              .frame(maxWidth: .infinity, alignment: .center)
              .focused($isFocused)
              .textInputAutocapitalization(.never)
              .disableAutocorrection(true)
              .onChange(of:isFocused)
              { newValue in
                  if !newValue
                  {
                      //Check Validation Errors
                      hasErrors = checkErrors(input: text)
                  }
                }
        }
    }
}

Upvotes: 1

Related Questions