Skip to Content

Form Validation trong SwiftUI

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

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) } } } } // Usage ValidatedTextField( label: "Email", text: $email, validation: { $0.contains("@") }, errorMessage: "Please enter a valid email" )

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

Button { // Submit } label: { if isLoading { ProgressView() } else { Text("Submit") } } .disabled(!isFormValid || isLoading) .opacity(isFormValid ? 1 : 0.5)

📝 Best Practices

  • Validate on change, not just on submit
  • Show errors near the field
  • Disable submit until valid
  • Use ViewModel for complex validation
Last updated on