Form Validation
1. Basic Validation
Phần tiêu đề “1. Basic Validation”struct SignUpForm: View { @State private var email = "" @State private var password = ""
var isEmailValid: Bool { email.contains("@") && email.contains(".") }
var isPasswordValid: Bool { password.count >= 8 }
var isFormValid: Bool { isEmailValid && isPasswordValid }
var body: some View { Form { TextField("Email", text: $email)
if !email.isEmpty && !isEmailValid { Text("Invalid email format") .foregroundColor(.red) .font(.caption) }
SecureField("Password", text: $password)
if !password.isEmpty && !isPasswordValid { Text("Password must be at least 8 characters") .foregroundColor(.red) .font(.caption) }
Button("Sign Up") { } .disabled(!isFormValid) } }}2. Real-time Validation
Phần tiêu đề “2. Real-time Validation”struct ValidatedTextField: View { let label: String @Binding var text: String let validation: (String) -> Bool let errorMessage: String
var body: some View { VStack(alignment: .leading, spacing: 4) { TextField(label, text: $text) .textFieldStyle(.roundedBorder) .overlay( RoundedRectangle(cornerRadius: 6) .stroke( !text.isEmpty && !validation(text) ? .red : .clear, lineWidth: 1 ) )
if !text.isEmpty && !validation(text) { Text(errorMessage) .foregroundColor(.red) .font(.caption) } } }}
// UsageValidatedTextField( label: "Email", text: $email, validation: { $0.contains("@") }, errorMessage: "Please enter a valid email")3. Form với ViewModel
Phần tiêu đề “3. Form với ViewModel”class FormViewModel: ObservableObject { @Published var email = "" @Published var password = "" @Published var confirmPassword = ""
var emailError: String? { guard !email.isEmpty else { return nil } return email.contains("@") ? nil : "Invalid email" }
var passwordError: String? { guard !password.isEmpty else { return nil } if password.count < 8 { return "Too short" } return nil }
var confirmError: String? { guard !confirmPassword.isEmpty else { return nil } return password == confirmPassword ? nil : "Passwords don't match" }
var isValid: Bool { emailError == nil && passwordError == nil && confirmError == nil && !email.isEmpty && !password.isEmpty && !confirmPassword.isEmpty }}4. Submit Button State
Phần tiêu đề “4. Submit Button State”Button { // Submit} label: { if isLoading { ProgressView() } else { Text("Submit") }}.disabled(!isFormValid || isLoading).opacity(isFormValid ? 1 : 0.5)📝 Best Practices
Phần tiêu đề “📝 Best Practices”- Validate on change, not just on submit
- Show errors near the field
- Disable submit until valid
- Use ViewModel for complex validation