allow only letters for User Name - swift3

I'm trying to limit the users First_Name to allow only letters so it should respond with an error for numbers or special characters after clicking on send_button. I found some examples here but because they are build on older swift version I'm having problems to make it work. Until now I've managed to read the First Name and throw an error if the first element on this textfield is not a letter but the code allow things like this (First name = "J123g") or ("Mark##$") and I don't want this to be the case.
func isOneLetter(in text: String) -> Bool {
do {
let regex = try NSRegularExpression(pattern: "[a-zA-Z]")
let nsString = text as NSString
let results = regex.matches(in: text, range: NSRange(location: 0, length: nsString.length))
let temp = results.map { nsString.substring(with: $0.range)}
return temp.isEmpty
} catch let error {
print("invalid regex: \(error.localizedDescription)")
return false
}
}
#IBAction func Send_Button(_ sender: AnyObject) {
let UserName = First_Name.text
if (isOneLetter(in: UserName!))
{
DisplayMyAlertMessage(userMessage: "First Name must contain only letter and spaces")
}
}

Your regex pattern checks for one alphanumeric character which matches both unwanted examples.
This regex checks for from beginning (^) to the end ($) of the string there must be one or more (+) alphanumeric characters ([a-zA-Z]). The benefit is that it treats an empty string also as bad.
^[a-zA-Z]+$

1st you have to inherit the UITextViewDelegate class with you own
class
class ViewController: UIViewController, UITextViewDelegate {
2nd add an IBOutlet
#IBOutlet weak var firstName: UITextField!
3rd you have to assure this object is using
override func viewDidLoad() {
super.viewDidLoad()
firstName.delegate = self
}
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
if textField == firstName {
let allowedCharacters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
let allowedCharacterSet = CharacterSet(charactersIn: allowedCharacters)
let typedCharacterSet = CharacterSet(charactersIn: string)
let alphabet = allowedCharacterSet.isSuperset(of: typedCharacterSet)
return alphabet
}
}

Another way could be:
let userInput = ""
let set = CharacterSet(charactersIn: "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLKMNOPQRSTUVWXYZ")
if userInput.rangeOfCharacter(from: set.inverted) != nil {
print("ERROR: There are numbers included!")
}

Updated for swift 3:
if you want to validate name and allow only letters for User Name then used below simple lines of code :
// function definition:
func isValidName(_ nameString: String) -> Bool {
var returnValue = true
let mobileRegEx = "[A-Za-z]{3}" // {3} -> at least 3 alphabet are compulsory.
do {
let regex = try NSRegularExpression(pattern: mobileRegEx)
let nsString = nameString as NSString
let results = regex.matches(in: nameString, range: NSRange(location: 0, length: nsString.length))
if results.count == 0
{
returnValue = false
}
} catch let error as NSError {
print("invalid regex: \(error.localizedDescription)")
returnValue = false
}
return returnValue
}
// function call :
var firstName = mEnterFirstNameTextField.text!
let isFirstNameValid = isValidName(firstName)
if isFirstNameValid{
// do user logic
}else{
// show error msg: -> "Enter name is not valid, please enter again..."
}

Related

Characters Validation of the Special Characters in the Text field

I want to change the background color of the view, while the text field has the Special characters like 123!#%^&() etc otherwise background colors should be the same color.
I have implemented but changing according to the each character it should not be like this if in entire text field any special character means color has to change.
Here is my code.
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
let specialCharacters = "!~`##$%^&*-+();:={}[],.<>?\\/\"\'"
let searchText = textField.text! + string
//
let character = CharacterSet(charactersIn: specialCharacters)
if (string.rangeOfCharacter(from: character) != nil){
print("matched")
self.view.backgroundColor = UIColor.gray
}else
{
self.view.backgroundColor = UIColor.white
}
Please find below working solutions Swift 4
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
                let specialCharacters = "!~`##$%^&*-+();:={}[],.<>?\\/\"\'"
                var searchText = textField.text! + string
              
                let characterSet = CharacterSet(charactersIn: specialCharacters)
                
                if string == "" {
                        searchText.removeLast()
                }
                
                if (string.rangeOfCharacter(from: characterSet) != nil) {
                        print("matched")
                        self.view.backgroundColor = UIColor.gray
                        textField.textColor = UIColor.white
                        return true
                } else  if (searchText.rangeOfCharacter(from: characterSet) == nil  ) {
                        self.view.backgroundColor = UIColor.white
                        textField.textColor = UIColor.black
                        return true
                }
                return true
        }

how to set the maximum 4 digit number in uitextfield using swift3.0

I use this code but it should return anyone. But I need to use this two scenarios. So how can I change this? Anyone help me. I restrict a (.0 symbol and at the same time only allowed 4 digit amount. How can i do this.???
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
guard let text = amountField.text else { return true }
let newLength = text.characters.count + string.characters.count - range.length
return newLength <= 4 // Bool
let ACCEPTABLE_CHARACTERS = "1234567890"
let cs = CharacterSet(charactersIn: ACCEPTABLE_CHARACTERS).inverted
let filtered: String = string.components(separatedBy: cs).joined(separator: "")
return string == filtered
}
Possible solution for your issue.
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
var newLength = string.utf16.count - range.length
if let text = textfield.text {
newLength = text.utf16.count + string.utf16.count - range.length
}
let characterSet = NSMutableCharacterSet()
characterSet.addCharacters(in: "1234567890")
if string.rangeOfCharacter(from: characterSet.inverted) != nil || newLength > 4 {
return false
}
return true
}

textfield validation for password and email

I want to implement the textfield validation for two textfielfd separately but I m unable to do so I have uplide delegates for both but they get applied for both the text fields for eg. email accepts only 10 chars how can we apply it separately for both email and mobile no separately Here is the code I have written:
func textFieldDidEndEditing(_ textField: UITextField, reason: UITextFieldDidEndEditingReason) {
if textField == textfieldemail
{
let providedEmailAddress = self.textfieldemail.text
let isEmailAddressValid = isValidEmailAddress(emailAddressString: providedEmailAddress!)
if isEmailAddressValid
{
print("Email address is valid")
}
else {
self.displayAlertMessage(messageToDisplay: "Email address is not valid")
}
}
}
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
let charsLimit = 10
let startingLength = textField.text?.characters.count ?? 0
let lengthToAdd = string.characters.count
let lengthToReplace = range.length
let newLength = startingLength + lengthToAdd - lengthToReplace
return newLength <= charsLimit
}
You can do that by giving tag to textfield and check that tag inside the fun to identify the textfield uniquely.
Assign UITextFieldDelegate to your respective ViewController
set delegate for the textField
emailIDTxtFld.delegate = self
mobileNoTxtFld.delegate = self
set tag for the textField
emailIDTxtFld.tag = 1001
mobileNoTxtFld.tag = 1002
Now implement these methods
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
let newString = (textField.text! as NSString).replacingCharacters(in: range, with: string)
if textField.tag == 1002{
//For MobileNo it will accept only 10 char
if newString.characters.count > 10{
return false
}else{
return true
}
}else if textField.tag == 1002{
//your logic
}
return true
}
func textFieldDidEndEditing(_ textField: UITextField) {
if textField.tag == 1001{
if textField.isValidEmail(){
// Code
}else{
print("Please Enter Vlaid Email ID")
}
}else if textField.tag == 1002{
if textField.text?.characters.count == 10{
// code
}else{
//code
}
}

Finding text between parentheses in Swift

How do you get an array of string values for the text between parentheses in Swift?
For example from: MyFileName(2015)(Type)(createdBy).zip
I would like: [2015,Type,createdBy]
Just updating the chosen answer to Swift 3:
func matchesForRegexInText(regex: String!, text: String!) -> [String] {
do {
let regex = try NSRegularExpression(pattern: regex, options: [])
let nsString = text as NSString
let results = regex.matches(in: text,
options: [], range: NSMakeRange(0, nsString.length))
return results.map { nsString.substring(with: $0.range)}
} catch let error as NSError {
print("invalid regex: \(error.localizedDescription)")
return []
}}
The usage remains the same.
Here is a complete example in Swift 4.2
func matchesForRegexInText(regex: String!, text: String!) -> [String] {
do {
let regex = try NSRegularExpression(pattern: regex, options: [])
let nsString = text as NSString
let results = regex.matches(in: text,
options: [], range: NSMakeRange(0, nsString.length))
return results.map { nsString.substring(with: $0.range)}
} catch let error as NSError {
print("invalid regex: \(error.localizedDescription)")
return []
}}
and usage :
let regex = "\\((.*?)\\)"
mmatchesForRegexInText(regex: regex, text: " exmaple (android) of (qwe123) text (heart) between parentheses")
You can use a regex for this
Thomas had a good example: \((.*?)\)
How to use a regex with Swift you can look up at: http://www.raywenderlich.com/86205/nsregularexpression-swift-tutorial
Here is my RegEx
which is actually trying to get the words between parentheses. E.g. (smile)
NSRegularExpression(pattern: "\\\\(\\\w+\\\\)",options:NSRegularExpressionOptions.CaseInsensitive)
it works for me!

Convert a JavaScript Regex to a Swift Regex

I'm learning Swift, and I'm trying to convert a small bit of JavaScript code to Swift. The JavaScript code uses a Regex to split up a string, as shown below:
var text = "blah.clah##something_else";
var parts = text.match(/(^.*?)\#\#(.+$)/);
after execution, the parts array will then contain the following:
["blah.clah##something_else", "blah.clah", "something_else"]
I would like to replicate the same behavior in Swift. Below is the Swift code I've written to do split up a String into a String array using a Regex:
func matchesForRegexInText(regex: String!, text: String!) -> [String] {
do {
let regex = try NSRegularExpression(pattern: regex, options: NSRegularExpressionOptions.CaseInsensitive)
let nsString = text as NSString
let results = regex.matchesInString(text,
options: NSMatchingOptions.ReportCompletion , range: NSMakeRange(0, nsString.length))
as [NSTextCheckingResult]
return results.map({
nsString.substringWithRange($0.range)
})
} catch {
print("exception")
return [""]
}
}
When I call the above function with the following:
matchesForRegexInText("(^.*?)\\#\\#(.+$)", text: "blah.clah##something_else")
I get the following:
["blah.clah##something_else"]
I've tried a number of different Regex's without success. Is the Regex (^.*?)\#\#(.+$) correct, or is there a problem with the matchesForRegexInText() function? I appreciate any insight.
I'm using Swift 2, and Xcode Version 7.0 beta (7A120f)
As already mentioned in a comment, your pattern matches the entire
string, so regex.matchesInString() returns a single
NSTextCheckingResult whose range describes the entire string.
What you are looking for are the substrings matching the capture groups
in your pattern. These are available as rangeAtIndex(i) with i >= 1:
func matchesForRegexInText(regex: String!, text: String!) -> [String] {
do {
let regex = try NSRegularExpression(pattern: regex, options: [])
let nsString = text as NSString
guard let result = regex.firstMatchInString(text, options: [], range: NSMakeRange(0, nsString.length)) else {
return [] // pattern does not match the string
}
return (1 ..< result.numberOfRanges).map {
nsString.substringWithRange(result.rangeAtIndex($0))
}
} catch let error as NSError {
print("invalid regex: \(error.localizedDescription)")
return []
}
}
Example:
let matches = matchesForRegexInText("(^.*?)##(.+$)", text: "blah.clah##something_else")
print(matches)
// [blah.clah, something_else]