简体   繁体   中英

How to have a firstname validation in iOS swift4?

I have a first name validation to be done in swift4 which is in a UITextField . The thing is that:

  1. The Firstname should start with a letter and end with a letter,
  2. No trailing and leading whitespace.
  3. It can have spaces between them, can contain dot.
  4. should be between 7 and 18 characters.

Currently i am having the following validation in the UITextField

public func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    let STRING_ACCEPTABLE_CHARACTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
    switch textField {
    case firstName:
        print("firstname")
        if string == " " {
            return false
        } else {
            let cs = NSCharacterSet(charactersIn: STRING_ACCEPTABLE_CHARACTERS).inverted
            let filtered = string.components(separatedBy: cs).joined(separator: "")
            return (string == filtered)
        }
    }
    return true
}

Any idea how to implement the following conditions. Right now I am disabling the space and only accepts the alphabets.

Any help will be very much appreciated

You can use regex to validate First name with your conditions.

I'm not an expert in regex, but here you can see an example

^[a-zA-Z](?:[a-zA-Z\.\s][^\n]*)[a-zA-Z]$

This regex will return you full matches. You can check, if any matches returned string is valid.

Link with example of usage regex in Swift.

Number of string characters you can check using Swift, like:

if string.count > 7 && string.count < 18 {
    //String valid
}

You can check the two conditions when you are taking the value from UITextField which are:

  1. Firstname should start and end with a letter
  2. Trimming whitespaces at the end.

And the rest conditions can be done inside shouldChangeCharactersInRange like below:

let STRING_ACCEPTABLE_CHARACTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz. "
    switch textField {
    case firstName:
        print("firstname")
        //Condition for always accepting backcspaces
        if string == "" {
            return true
        }
        //Condition for restricting space at the begining
        else if textField.text?.count == 0 && string == " " {
            return false
        }
        //Condition for restricing user from entering more than 18 letters
        else if (textField.text?.count)! > 17 {
          return false
        }
        //Condition for only accepting the alphabets.
        else {
            let cs = NSCharacterSet(charactersIn: STRING_ACCEPTABLE_CHARACTERS).inverted
            let filtered = string.components(separatedBy: cs).joined(separator: "")
            return (string == filtered)
        }

For checking the minimum number of letters, trimming whitespaces at the end and starting and ending with a letter with below conditions inside a Button's click or something equivalent to it:

//Trimming whitespaces at the end
let firstname = firstName.text?.trimmingCharacters(in: .whitespaces)

let letters = NSCharacterSet.letters

let prefix = String((firstname?.first)!)
let suffix = String((firstname?.last)!)

//Checking if First Character is letter
if let _ = prefix.rangeOfCharacter(from: letters) {
    print("letters found")
} else {
    print("letters not found")
}

//Checking if Last Character is letter
if let _ = suffix.rangeOfCharacter(from: letters) {
    print("letters found")
} else {
    print("letters not found")
}

Hope this helps.

You can use this func for short and clean way

func isValid(testStr:String) -> Bool {
    guard testStr.count > 7, testStr.count < 18 else { return false }

    let predicateTest = NSPredicate(format: "SELF MATCHES %@", "^(([^ ]?)(^[a-zA-Z].*[a-zA-Z]$)([^ ]?))$")
    return predicateTest.evaluate(with: testStr)
}

Test cases

isValid(testStr: " MyNameIsDahiya") // Invalid, leading space
isValid(testStr: "MyNameIsDahiya ") // Invalid, trailing space
isValid(testStr: " MyNameIsDahiya ") // Invalid, leading & trailing space
isValid(testStr: "1MyNameIsDahiya") // Invalid, Leading num
isValid(testStr: "MyNameIsDahiya1") // Invalid, trailing num
isValid(testStr: "1MyNameIsDahiya1") // Invalid, leading & trailing num
isValid(testStr: "MyName") // Invalid, length below 7
isValid(testStr: "MyNameIsDahiyaBlahhblahh") // Invalid, length above 18

isValid(testStr: "MyNameIsDahiya") // Valid,
isValid(testStr: "Mr. Dahiya") // Valid,

Playground Test

在此输入图像描述

Edit

Try this below regex:

(?mi)^[a-z](?!(?:.*\.){2})(?!(?:.* ){2})(?!.*\.[a-z])[a-z. ]{5,16}[a-z]$

It will validate all the conditions and length also.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM