Reputation: 85
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
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