How to get range of textField text till 6 characters? - ios

I've a UITextField for entering pincode number.
My requirement is when textField character range reach to 6th character then I've to do server validation and I have to put the data in labels. If character range is less than 5 then I will pass nil value.
Below is my code :-
//TextField character range
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
if textField == pinCode
{
guard let text = textField.text else { return true }
let newLength = text.characters.count + string.characters.count - range.length
if(5 >= newLength)
{
print(newLength)
}
else
{
if newLength == 6
{
serverValidation()
print(textField.text!)
setFields(city: "Ajmer", state: "Rajasthan", country: "India")
return newLength <= 6
}
else
{
return newLength <= 6
}
}
}
return true
}
My problem is when (newLength == 6) then I'm getting textField text of 5 characters only. I mean if suppose zip code is 560068 then text I'm getting 56006 only. (But I've to do server validation in that condition only for 6 characters zip code)
So if (newLength == 6) then how can I get 6 characters in text field, and then I can do server validation here only.
I'm new in swift.
Thanks

shouldChangeCharactersIn will get called prior to getting the actual text in the UITextField
This is how you get the full text from that UITextField
let newString = NSString(string: textField.text!).replacingCharacters(in: range, with: string)
Edit
this is how you can use it
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
if textField == pinCode
{
guard let text = textField.text else { return true }
let newString = NSString(string: textField.text!).replacingCharacters(in: range, with: string)
let newLength = newString.characters.count
if(5 >= newLength)
{
print(newLength)
}
else
{
if newLength == 6
{
serverValidation()
print(newString)
setFields(city: "Ajmer", state: "Rajasthan", country: "India")
return newLength <= 6
}
else
{
return newLength <= 6
}
}
}
return true
}

Use TextField delegates method for this.
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
let currentCharacterCount = textField.text?.characters.count ?? 0
if (range.length + range.location > currentCharacterCount+1)
{
return false
}
print(currentCharacterCount)
let newLength = currentCharacterCount + string.characters.count - range.length
return newLength <= 6 //this will not allow you to enter more than 6 characters
}
After that call
func textFieldDidEndEditing(_ textField: UITextField)
{
print(textField.text!)
setFields(city: "Ajmer", state: "Rajasthan", country: "India")
}
to call this method you can use view.endEditing(true) method.

You should get newlength from textfield.text.length + string.length
then get the text from textfield.text + string.
You can't get new text from textfield.text before call return true.

Try this
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
if textField == pinCode
{
guard let text = textField.text else { return true }
var txtAfterUpdate:NSString = textField.text! as NSString
txtAfterUpdate = txtAfterUpdate.stringByReplacingCharactersInRange(range, withString: string)
let txtString = txtAfterUpdate as String
let newLength = txtString.characters.count
if(5 >= newLength)
{
print(newLength)
}
else
{
if newLength == 6
{
print(textField.text!)
setFields(city: "Ajmer", state: "Rajasthan", country: "India")
return newLength <= 6
}
else
{
return newLength <= 6
}
}
}
return true
}

Related

maxLength for switch text field

I have several text fields, each with a different number of maximum characters. How can I change the if branch to enum and use switch?
//if -> switch
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
let newLength = (textField.text ?? "").count + string.count - range.length
if(textField == textFieldA) {
return newLength <= 6
}
if(textField == textFieldB) {
return newLength <= 7
}
if(textField == textFieldC) {
return newLength <= 8
}
return true
}
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
let newLength = (textField.text ?? "").count + string.count - range.length
switch textField {
case textFieldA :
return newLength <= 6
case textFieldB:
return newLength <= 7
case textFieldC:
return newLength <= 8
default:
return true
}
}
You are comparing one field to multiple fields using == so you should be able to just do it like below:
switch (textField) {
case textFieldA:
return newLength <= 6
case textFieldB:
return newLength <= 7
case textFieldC:
return newLength <= 8
default:
return true
}

Issue with restrict limit characters & restrict special charecters in swift?

I am creating a OTP Screen on that screen i have added 6 text fields.Now i want to restrict to enter only ONE charecter & also want to restrict user not to enter any special charecters.Below is the code i have used,Please review the code & let me know what is wrong ?
let notAllowedCharacters = "!##$%^&*()_+{},./[]?:;";
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange,replacementString string: String) -> Bool
{
guard let text = textField.text else { return true }
let newLength = text.characters.count + string.characters.count - range.length
if newLength <= 1 {
return true
}
else {
let set = NSCharacterSet(charactersIn: notAllowedCharacters);
let filtered = string.components(separatedBy: set as CharacterSet).joined(separator: "")
return filtered == string;
}
}
You need to add the control of your NSCharacterSet when you make the check for the characters length. Otherwise it will always be true regardless character if there is always one character. Update your code to the following and it will work for you:
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange,replacementString string: String) -> Bool {
guard let text = textField.text else { return true }
let newLength = text.characters.count + string.characters.count - range.length
let set = NSCharacterSet(charactersIn: notAllowedCharacters)
if newLength <= 1 && !(string.rangeOfCharacter(from: set as CharacterSet) != nil) {
return true
} else {
return false
}
}

How to set the maximum number of value during typing

I have a UITextField, I'd like to restrict the maximum allowed input value in the field to be 1000 .eg (1-1000),If the value in the textfield exceeds above 1000 the textfield should not get the value as input.I have tried the following
func textField(_ textField: UITextField,shouldChangeCharactersIn range: NSRange,replacementString string: String) -> Bool
{
var newString: String = textField.text.replacingCharacters(in: range, with: string)
var characterSet = CharacterSet(charactersIn: "0123456789,.").inverted
if (newString as NSString).rangeOfCharacter(from: characterSet).location != NSNotFound {
return false
}
return Double(newString) ?? 0.0 < 1000
}
Try this. Hope this will help
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
guard let text = textField.text else { return true }
let newLength = text.characters.count + string.characters.count - range.length
return newLength <= 1001
}
Try extracting the integer value from the textField and check if it is below 1000.
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
NSInteger inte = [textField.text intValue];
if (inte < 1000 && inte > 0)
return NO;
else
return YES;
}

How to restrict double/single space for TextField in Swift 3 iOS

I have login page in my iOS app which is developing by Swift language.
In that first letter should not be with single/double space and after user enters text it should allow single space, not allow double space and need to set the limit for text length.
I want to restrict the user while tapping single/double space while starting time entering text and need to allow single space after enters first letter in textfield
I am able to do either one of single/double, but not working as per my requirement.
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
//for double space restrict
if (range.location > 0 && (textField.text?.characters.count)! > 0) {
//Manually replace the space with your own space, programmatically
//Make sure you update the text caret to reflect the programmatic change to the text view
//Tell Cocoa not to insert its space, because you've just inserted your own
return false
}else {
if textField.tag == 1 || textField.tag == 2 { //restrict text length
guard let text = textField.text else { return true }
let newLength = text.characters.count + string.characters.count - range.length
return newLength <= limitLengthForTextField
}
}
return true
}
Can anyone give suggestions. Thanks
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
let rawString = string
let range = rawString.rangeOfCharacter(from: .whitespaces)
if ((textField.text?.characters.count)! == 0 && range != nil)
|| ((textField.text?.characters.count)! > 0 && textField.text?.characters.last == " " && range != nil) {
return false
}
return true
}
Try This Code:
//TextField Validation
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool
{
if(textField == UserNameText)
{
if range.location == 0 && string == " "
{
return false
}
return true
}
else if(textField == PasswordText)
{
if range.location == 0 && string == " "
{
return false
}
return true
}
else
{
return true
}
}
It Wont allow users to give space at first letter. For Example if you need to set limit for username field and its limit is 10 characters means use this code:
//TextField Validation
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool
{
if(textField == UserNameText)
{
if range.location == 0 && string == " "
{
return false
}
else if range.length + range.location > (self. UserNameText.text?.characters.count)!
{
return false
}
let NewLength = (self.let NewLength = (self.userEmailTxt.text?.characters.count)! - range.length
return NewLength <= 9
}
else if(textField == PasswordText)
{
if range.location == 0 && string == " "
{
return false
}
return true
}
else
{
return true
}
}
try this
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
let result = (textField.text as NSString?)?.replacingCharacters(in: range, with: string) ?? string
let text = result as String
if (text.range(of: "^(?i)(?![ ])(?!.*[ ]{2})[A-Z. ]*$", options: .regularExpression) != nil) {
return true
}
return false
}
If you need to restrict total length update the regex to ^(?i)(?![ ])(?!.*[ ]{2})[A-Z. ]{1,10}$ for 10 chars. Update the length as required.
Please check this code.
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
let trimmedString = textField.text?.trimmingCharacters(in: .whitespaces)
if (trimmedString.length == 0)
return false
//for double space restrict
if (range.location > 0 && (textField.text?.characters.count)! > 0) {
//Manually replace the space with your own space, programmatically
//Make sure you update the text caret to reflect the programmatic change to the text view
//Tell Cocoa not to insert its space, because you've just inserted your own
if string.range(of:" ") != nil {
return false
}
return true
}else {
if textField.tag == 1 || textField.tag == 2 { //restrict text length
guard let text = textField.text else { return true }
let newLength = text.characters.count + string.characters.count - range.length
return newLength <= limitLengthForTextField
}
}
return true
}
And your code for restricting textfield length should work fine as it is for textfields with tag 1 & 2.
It works !
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool
{
if (string == " " || string == " ") && range.location == 0
{
return false
}
return true
}
func textField(_ textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
if range.location == 0 && string == " " {
return false
} else if range.location > 1 && textField.text?.characters.last == " " && string == " " {
return false
}else{
return true
}
}
Hi, Anli please try this it will solve your problem.
Swift 4.1
Just simple with Single line of code you can stop whitespace
For All Textfield
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
textField.text = textField.text?.replacingOccurrences(of: " ", with: "")
return true
}
For Single Textfield
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
if textField == txtid
{
textField.text = textField.text?.replacingOccurrences(of: " ", with: "")
}
return true
}
I found answer finally for my requirement
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
//for double space restrict
let str = textField.text
if str?.characters.count == 0 && string == " " {
return false
} else if (str?.characters.count)! > 0 {
if str?.characters.last == " " && string == " " {
return false
} else {
if textField.tag == 1 || textField.tag == 2 { //restrict text length
guard let text = textField.text else { return true }
let newLength = text.characters.count + string.characters.count - range.length
return newLength <= limitLengthForTextField
}
}
}
return true
}
Swift 5.0
Only allow single space in textField text change with Error handling:
func textField(textField: UITextField,
shouldChangeCharactersInRange
range: NSRange, replacementString string: String) -> Bool {
let (isValid, errorMessage) = validateSpacesInTextChange(newText: string, existingText: textField.text!, in: NSRange)
return isValid
}
func validateSpacesInTextChange(newText: String,
existingText: String,
in range: NSRange) -> (Bool, errorMessage: String?) {
let range = newText.rangeOfCharacter(from: .whitespaces)
let textNotStartWithSpace = !(existingText.isEmpty && range != nil)
guard textNotStartWithSpace else { return (false, "Space not allowed at the Begning") }
let notContainTwoSpaces = !(!existingText.isEmpty && existingText.last == " " && range != nil)
guard notContainTwoSpaces else { return (false, "Only single space allowed") }
return (true, nil)
}

Identical textField functions in swift

I have two identical functions in my ViewController and it seems that neither of them can be renamed.
The first one is used to limit characters and show the number left.
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
if let textField = textField as? UITextField {
if (range.length + range.location > textField.text!.characters.count) {
return false;
}
let newLength = textField.text!.characters.count + string.characters.count - range.length;
cLabel.text = String(25 - newLength)
return newLength <= 25 // To just allow up to … characters
}
return true;
}
The second one enables a button when text is added to the same textField.
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
// Find out what the text field will be after adding the current edit
let text = (ahskField.text! as NSString).stringByReplacingCharactersInRange(range, withString: string)
if text.isEmpty{//Checking if the input field is not empty
ahskButton.userInteractionEnabled = false //Enabling the button
ahskButton.enabled = false
} else {
ahskButton.userInteractionEnabled = true //Disabling the button
ahskButton.enabled = true
}
// Return true so the text field will be changed
return true
}
Is there a way to combine them or anything?
You only need one of the shouldChangeCharactersInRange functions.
Put all of your logic in the one method.
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
// Find out what the text field will be after adding the current edit
let text = (textField.text! as NSString).stringByReplacingCharactersInRange(range, withString: string)
let newLength = text.characters.count
if newLength <= 25 {
cLabel.text = String(25 - newLength)
if text.isEmpty { //Checking if the input field is not empty
ahskButton.userInteractionEnabled = false //Enabling the button
ahskButton.enabled = false
} else {
ahskButton.userInteractionEnabled = true //Disabling the button
ahskButton.enabled = true
}
return true;
} else {
return false;
}
}

Resources