I like to validate each text field depending on the content that should be provided by the user, i.e. emailTextField
should contain a valid email address etc. While Ashley Mills answer is convenient, if you regard whitespace " "
as text this will return false.
In your case, since you need to validate multiple text fields in the same way, why not extend UITextField
as Ashley did with a static class method that can validate each text field passed as an array, in addition to this have other validation methods for each type of text field. Instead of returning a Boolean value I've learned to use guard
instead. In this way guard let
can be used to check if the validation fails (is nil) and execute the proper code, such as displaying a prompt to the user, or otherwise continue execution.
UITextFieldExtension.swift
import Foundation
import UIKit
extension UITextField {
/// Validates all text field are non-nil and non-empty, Returns true if all fields pass.
/// - Returns: Bool
static func validateAll(textFields:[UITextField]) -> Bool {
// Check each field for nil and not empty.
for field in textFields {
// Remove space and new lines while unwrapping.
guard let fieldText = field.text?.trimmingCharacters(in: .whitespacesAndNewlines) else {
return false
}
// Are there no other charaters?
if (fieldText.isEmpty) {
return false
}
}
// All fields passed.
return true
}
//A function that validates the email address...
func validateEmail(field: UITextField) -> String? {
guard let trimmedText = field.text?.trimmingCharacters(in: .whitespacesAndNewlines) else {
return nil
}
//email addresses are automatically detected as links in i0S...
guard let dataDetector = try? NSDataDetector(types: NSTextCheckingResult.CheckingType.link.rawValue) else {
return nil
}
let range = NSMakeRange(0, NSString(string: trimmedText).length)
let allMatches = dataDetector.matches(in: trimmedText,
options: [],
range: range)
if allMatches.count == 1,
allMatches.first?.url?.absoluteString.contains("mailto:") == true
{
return trimmedText
}
return nil
}
func validateUserName(field: UITextField) -> String? {
guard let text:String = field.text else {
return nil
}
/* 3 to 12 characters, no numbers or special characters */
let RegEx = "^[^\\d!@#£$%^&*<>()/\\\\~\\[\\]\\{\\}\\?\\_\\.\\`\\'\\,\\:\\;|\"+=-]+$"
let Test = NSPredicate(format:"SELF MATCHES %@", RegEx)
let isValid = Test.evaluate(with: text)
if (isValid) {
return text
}
return nil
}
/*6 to 16 Characters */
func validatePassword(field: UITextField) -> String?{
guard let text:String = field.text else {
return nil
}
/*6-16 charaters, and at least one number*/
let RegEx = "^(?=.*\\d)(.+){6,16}$"
let Test = NSPredicate(format:"SELF MATCHES%@", RegEx)
let isValid = Test.evaluate(with: text)
if (isValid) {
return text
}
return nil
}
}
Meanwhile, elsewhere...
if (UITextField.validateAll(textFields: [emailTextField, nameTextField])) {
// Do something
}