Hello! This is my first time posting a question on a form. So sorry ahead of time if I am not doing something right and please let me know how I can fix it!
I am new to swift and I have been following a video by AppStuff. https://youtu.be/QJHmhLGv-_0?si=OwLGXKNTc3m-UH7r&t=5914 . The link is time stamped to the part of the video I need help with.
My question is: Where do I put the AuthenticationFormProtocol var formIsValid
so that way I can call on formIsValid to use the .disabled and .opacity in the ButtonView File depending on if formIsValid is true or not?
I deviated from the video by making a new file called ButtonView so that way I didn't have to copy and paste code that I would be using in two different places.
ButtonView File
import SwiftUI
struct ButtonView: View {
let printTitle: String
let title: String
let systemIcon: String
//@Binding var disabledPlaceHolder: String
let taskAction: () -> Void
var body: some View {
Button(action: {
taskAction()
}) {
HStack {
Text(title)
.fontWeight(.semibold)
Image(systemName: systemIcon)
}
.foregroundStyle(Color(.white))
.frame(width: UIScreen.main.bounds.width - 32, height: 48)
}
.background(Color(.systemBlue))
//.disabled(disabledPlaceHolder)
//.opacity(disabledPlaceHolder ? 1.0 : 0.5)
.clipShape(RoundedRectangle(cornerRadius: 10))
.padding(.bottom, 50)
}
}
#Preview {
ButtonView(printTitle: "Sign user up...",
title: "Sign Up",
systemIcon: "arrow.right",
//disabledPlaceHolder: .constant(""),
taskAction: {})
}
LoginView File
import SwiftUI
struct LoginView: View {
@State private var email = ""
@State private var password = ""
@EnvironmentObject var viewModel: AuthViewModel
var body: some View {
NavigationStack {
VStack {
//image
Image("TestLogo")
.resizable()
.scaledToFill()
.frame(width: 100, height: 120)
.clipShape(RoundedRectangle(cornerRadius: 20))
.padding(.vertical, 32)
//form fields
VStack(spacing: 24) {
InputView(text: $email,
title: "Email",
placeholder: "name@example.com")
.textInputAutocapitalization(.none)
InputView(text: $password,
title: "Password",
placeholder: "Enter your password",
isSecureField: true)
}
.padding(.horizontal)
.padding(.top, 12)
//sign in button
ButtonView(printTitle: "Login In",
title: "SIGN IN",
systemIcon: "arrow.right") {
Task {
try await viewModel.signIn(withEmail: email,
password: password)
}
}
// .disabled(formIsValid)
// .opacity(formIsValid ? 1.0 : 0.5)
Spacer()
//signup button
NavigationLink {
RegistrationView()
.navigationBarBackButtonHidden(true)
} label: {
HStack(spacing: 3) {
Text("Don't have an account?")
Text("Sign Up")
.fontWeight(.bold)
}
.font(.system(size: 14))
}
}
}
}
}
extension LoginView: AuthenticationFormProtocol {
var formIsValid: Bool {
return !email.isEmpty
&& email.contains("@")
&& !password.isEmpty
&& password.count > 5
}
}
RegistationView File
struct RegistrationView: View {
@State private var email = ""
@State private var fullName = ""
@State private var password = ""
@State private var confirmPassword = ""
@EnvironmentObject var viewModel: AuthViewModel
@Environment(\.dismiss) var dismiss
var body: some View {
VStack {
//image
Image("TestLogo")
.resizable()
.scaledToFill()
.frame(width: 100, height: 120)
.clipShape(RoundedRectangle(cornerRadius: 20))
.padding(.vertical, 32)
//form fields
VStack(spacing: 24) {
InputView(text: $email,
title: "Email",
placeholder: "name@example.com")
.textInputAutocapitalization(.none)
InputView(text: $fullName,
title: "Full name",
placeholder: "Enter your name")
InputView(text: $password,
title: "Password",
placeholder: "Enter your password",
isSecureField: true)
InputView(text: $confirmPassword,
title: "Confirm Password",
placeholder: "Confirm your password",
isSecureField: true)
}
.padding(.horizontal)
.padding(.top, 12)
//sign up button
ButtonView(printTitle: "Create User",
title: "CREATE USER",
systemIcon: "arrow.right") {
Task {
try await viewModel.createUser(withEmail: email,
password: password,
fullname: fullName)
}
}
// .disabled(formIsValid)
// .opacity(formIsValid ? 1.0 : 0.5)
Spacer()
Button {
dismiss()
} label: {
HStack(spacing: 3) {
Text("Already have an account?")
Text("Sign In")
.fontWeight(.bold)
}
.font(.system(size: 14))
}
}
}
}
extension RegistrationView: AuthenticationFormProtocol {
var formIsValid: Bool {
return !email.isEmpty
&& email.contains("@")
&& !password.isEmpty
&& password.count > 5
&& confirmPassword == password
&& !fullName.isEmpty
}
}