Problem... I have a string of allowable characters "0123456789." How do I also allow the backspace from the keyboard... when I implement the code from below... the backspace key no longer works... How can I fix this?
- (BOOL) textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
NSCharacterSet *nonNumberSet = [[NSCharacterSet characterSetWithCharactersInString:#"0123456789."] invertedSet];
return ([string stringByTrimmingCharactersInSet:nonNumberSet].length > 0);
}
- (BOOL) textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
NSCharacterSet *nonNumberSet = [[NSCharacterSet characterSetWithCharactersInString:#"0123456789."] invertedSet];
if (range.length == 1){
return YES;
}else{
return ([string stringByTrimmingCharactersInSet:nonNumberSet].length > 0);
}
}
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
if ([string length] == 0)
return YES;
NSCharacterSet *nonNumberSet = [[NSCharacterSet decimalDigitCharacterSet] invertedSet];
string = [[string componentsSeparatedByCharactersInSet:nonNumberSet] componentsJoinedByString:#""];
textField.text = [textField.text stringByReplacingCharactersInRange:range withString:string];
return NO;
}
This should work correctly with deleting/cutting multiple characters at once, as well as pasting. Corrections welcome. The only known problem is that when you edit in the middle of the text field the cursor gets sent to the end (because it returns NO) -- I guess you have to use a UITextView to fix that.
NSCharacterSet *theNonNumberSet = [[NSCharacterSet characterSetWithCharactersInString:#"0123456789."] invertedSet];
if (range.length == 1){
return YES;
}else if(textField.text.length < ZipcodeTextLength)
{
return ([string stringByTrimmingCharactersInSet:theNonNumberSet].length > 0);
}
else
return NO;
This will allow Numbers and Backspace and also you can limit the text length.
This is one of my implementations. Maybe it works for you.
-(BOOL) textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
for(UIView *view in _chooseUsernameDialog.subviews) {
if([view isKindOfClass:[UIButton class]]) {
int realLength;
const char * _char = [string cStringUsingEncoding:NSUTF8StringEncoding];
int isBackSpace = strcmp(_char, "\b");
if (isBackSpace == -8) {
// is backspace
realLength = [textField.text length] - 1 ;
}
else
{
realLength = [textField.text length] + 1;
}
NSLog(#"%d", realLength );
if(realLength < 4)
{
//too short
}
else{
//long enough
}
}
}
return !([[textField text] length] + (string.length - range.length) > 13);
}
Related
I need to restrict user to enter only two digit after decimal point. I have achieved this by following code in textfield delegate shouldChangeCharactersInRange. But its allowing to enter more than one dot. how to restrict this? Thanks in advance.
NSString *newString = [textField.text stringByReplacingCharactersInRange:range withString:string];
NSArray *sep = [newString componentsSeparatedByString:#"."];
if([sep count]>=2)
{
NSString *sepStr=[NSString stringWithFormat:#"%#",[sep objectAtIndex:1]];
NSLog(#"sepStr:%#",sepStr);
return !([sepStr length]>2);
}
return YES;
The best way is to use Regular Expression in shouldChangeCharactersInRange: delegate method like this
-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{
NSString *newStr = [textField.text stringByReplacingCharactersInRange:range withString:string];
NSString *expression = #"^([0-9]*)(\\.([0-9]+)?)?$";
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:expression
options:NSRegularExpressionCaseInsensitive
error:nil];
NSUInteger noOfMatches = [regex numberOfMatchesInString:newStr
options:0
range:NSMakeRange(0, [newStr length])];
if (noOfMatches==0){
return NO;
}
return YES;
}
After implementing this valid strings are:
12.004546
4546.5456465
.5464
0.454
So on....
You can also restrict number of integer after decimal by using this Regular Expression#"^([0-9]*)(\\.([0-9]{0,2})?)?$"
After implementing this valid strings are:
12.00
4546.54
.54
0.45
-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{
NSString *sepStr;
NSString *newString = [textField.text stringByReplacingCharactersInRange:range withString:string];
NSArray *sep = [newString componentsSeparatedByString:#"."];
if([sep count]>=2)
{
sepStr=[NSString stringWithFormat:#"%#",[sep objectAtIndex:1]];
NSLog(#"sepStr:%#",sepStr);
if([sepStr length] >2)
{
return NO;
}
else
{
return YES;
}
}
return YES;
}
When a dot is entered, you should check whether a dot is present already, and return NO if it is present.
NSString * newString = [textField.text stringByReplacingCharactersInRange: range withString: string];
NSArray * sep = [newString componentsSeparatedByString: #"."];
if([string isEqualToString:#"."] && [sep count] > 1){
//already a . is there.. so don't allow new one
return NO;
}
if ([sep count] >= 2) {
NSString * sepStr = [NSString stringWithFormat: #"%#", [sep objectAtIndex: 1]];
NSLog(#"sepStr:%#", sepStr);
return !([sepStr length] > 2);
}
return YES;
Updated answer for Swift 3 using the reg ex "^([0-9]*)(\\.([0-9]+)?)?$":
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
let newText = ((textField.text ?? "") as NSString).replacingCharacters(in: range, with: string)
let expression = "^([0-9]*)(\\.([0-9]+)?)?$"
guard let regex = try? NSRegularExpression(pattern: expression, options: .caseInsensitive) else {
return false
}
let noOfMatches = regex.numberOfMatches(in: newText, options: [], range: NSMakeRange(0, newText.characters.count))
return noOfMatches > 0
}
You can use this method:
-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
NSRange temprange = [textField.text rangeOfString:#"."];
if ((temprange.location != NSNotFound) && [string isEqualToString:#"."])
{
return NO;
}
return YES;
}
NSString *newString = [textField.text stringByReplacingCharactersInRange:range withString:string];
NSArray *sep = [newString componentsSeparatedByString:#"."];
if([string isEqualToString:#"."]){
if([textField.text containsString:#"."]){
return NO;
}
}
if([sep count] >= 2)
{
NSString *sepStr=[NSString stringWithFormat:#"%#",[sep objectAtIndex:1]];
return !([sepStr length]>2);
}
return YES;
}
I have one UITextField which will display some value like "rocky". If I delete this text from the text field then I want the fields text to immediately change back to the original text.
You need a small change see my answer :
- (BOOL)textField:(UITextField *)theTextField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
NSString *newString = [textField.text stringByReplacingCharactersInRange:range withString:string];
if([newString isEqualToString:#""]){
textField.text=#"rocky";
return NO;
}
return YES;
}
You can notice the difference.Just return NO for your empty string case.
Intially add NSString *strName as class object.in viewDidLoad add this
strName = #"Rocky";
Now
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
if([[string stringByReplacingOccurrencesOfString:#" "
withString:#""] isEqualToString:#""]){
textField.text=strName;
}
else
{
strName = text; //change name here for keeping record
}
return YES;
}
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
NSString *newString = [textField.text stringByReplacingCharactersInRange:range withString:string];
if(newString.length==0) {
txtProjectName.text=#"rocky";
textField.userInteractionEnabled=NO;
return NO;
}
return YES;
}
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
if(textField.length==0) {
txtProjectName.text=#"rocky";
return NO;
}
return YES;
}
Try this.
I have two text fields that I would like to limit the number and type of characters. I have used the following bits of code to do each function separately but cannot find a way to do both within the same function.
To restrict the type of character:
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
// Only characters in the NSCharacterSet you choose will insertable.
NSCharacterSet *invalidCharSet = [[NSCharacterSet characterSetWithCharactersInString:#"abcdefgABCDEFG"] invertedSet];
NSString *filtered = [[string componentsSeparatedByCharactersInSet:invalidCharSet] componentsJoinedByString:#""];
return [string isEqualToString:filtered];
}
and to limit the number of characters:
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
if (textField.text.length >= 10 && range.length == 0)
return NO;
return YES;
}
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
if (textField.text.length >= 10 && range.length == 0)
return NO;
// Only characters in the NSCharacterSet you choose will insertable.
NSCharacterSet *invalidCharSet = [[NSCharacterSet characterSetWithCharactersInString:#"abcdefgABCDEFG"] invertedSet];
NSString *filtered = [[string componentsSeparatedByCharactersInSet:invalidCharSet] componentsJoinedByString:#""];
return [string isEqualToString:filtered];
}
Edited
If you want to add different condition for third text field then you can do like this.
Create the reference for 3rd text fild say thirdField
then use this
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
if (textField == thirdField) {
//your contion e.g
if (textField.text.length < 7) {
return YES;
} else {
return NO;
}
}
else {
if (textField.text.length >= 10 && range.length == 0)
return NO;
// Only characters in the NSCharacterSet you choose will insertable.
NSCharacterSet *invalidCharSet = [[NSCharacterSet characterSetWithCharactersInString:#"abcdefgABCDEFG"] invertedSet];
NSString *filtered = [[string componentsSeparatedByCharactersInSet:invalidCharSet] componentsJoinedByString:#""];
return [string isEqualToString:filtered];
}
}
Here is one of the cleanest approaches to restricting characters entered in a UITextField. This approach allows the use of multiple predefined NSCharacterSets.
-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{
NSMutableCharacterSet *allowedCharacters = [NSMutableCharacterSet alphanumericCharacterSet];
[allowedCharacters formUnionWithCharacterSet:[NSCharacterSet whitespaceCharacterSet]];
[allowedCharacters formUnionWithCharacterSet:[NSCharacterSet symbolCharacterSet]];
[allowedCharacters addCharactersInString:#":./"]; //allow arbitrary characters
if([string rangeOfCharacterFromSet:allowedCharacters.invertedSet].location == NSNotFound){
return YES;
}
return NO;
}
This is the way:
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
// Only characters in the NSCharacterSet you choose will insertable.
NSCharacterSet *invalidCharSet = [[NSCharacterSet characterSetWithCharactersInString:#"abcdefgABCDEFG"] invertedSet];
NSString *filtered = [[string componentsSeparatedByCharactersInSet:invalidCharSet] componentsJoinedByString:#""];
bool cond1 = [string isEqualToString:filtered];
if (textField.text.length >= 10 && range.length == 0){
return NO;
}else{
return (cond1);
}
}
I am using textfield in my application and I want to restrict user typing only 15 characters in the textfield. After that he/she should not be able to type in the textfield.
How can I set this kind of functionality?
There's a bit of a trick to this, you need to calculate what the new string will be before you can test whether to allow or deny the change
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
NSString *newString = [textField.text stringByReplacingCharactersInRange:range withString:string];
if ([newString length] > 15) {
return FALSE;
} else {
return TRUE;
}
}
//its big code but working fine for me
//put Your Text Field Name instead of YourTextFieldName in this code
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
if (textField==YourTextFieldName)
{
NSString *text = nil;
int MAX_LENGTH = 12;
text = YourTextFieldName.text;
if ([text length] <= 7)
{
NSString *separator = #"-";
int seperatorInterval = 3;
NSString *originalString = [textField.text stringByReplacingOccurrencesOfString:separator withString:#""];
if (![originalString isEqualToString:#""] && ![string isEqualToString:#""])
{
NSString *lastChar = [YourTextFieldName.text substringFromIndex:[YourTextFileName.text length] - 1];
int modulus = [originalString length] % seperatorInterval;
if (![lastChar isEqualToString:separator] && modulus == 0)
{
YourTextFieldName.text = [YourTextFieldName.text stringByAppendingString:separator];
}
}
}
if ([text length] > 7)
{
NSString *separator = #"-";
int seperatorInterval = 6;
NSString *originalString = [textField.text stringByReplacingOccurrencesOfString:separator withString:#""];
if (![originalString isEqualToString:#""] && ![string isEqualToString:#""])
{
NSString *lastChar = [YourTextFieldName.text substringFromIndex:[YourTextFieldName.text length] - 1];
int modulus = [originalString length] % seperatorInterval;
if (![lastChar isEqualToString:separator] && modulus == 0)
{
YourTextFieldName.text = [YourTextFieldName.text stringByAppendingString:separator];
}
}
}
NSUInteger newLength = [textField.text length] + [string length] - range.length;
return (newLength > MAX_LENGTH) ? NO : YES;
}
return YES;
}
You can check if typing and count chars
(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
if (range.length > 15) {
// delete
}
else
{
// add
}
}
use method
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
if (([textField.text length] - range.length) == 15) {
return NO;
}
return YES;
}
hope it helps. happy coding :)
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
if (textField.text.length >= 15)
{
return NO; //return NO to not change text
}
return YES;
}
How can I correct this code. I want only numbers and range should be not exceed to 10.
My code is
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
NSUInteger newLength = [textField.text length] + [string length] - range.length;
return (newLength > 10) ? NO : YES;
static NSCharacterSet *charSet = nil;
if(!charSet) {
charSet = [[[NSCharacterSet characterSetWithCharactersInString:#"0123456789"] invertedSet] retain];
}
NSRange location = [string rangeOfCharacterFromSet:charSet];
return (location.location == NSNotFound);
}
The problem here is that anything after the first return is not executed.
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
NSUInteger newLength = [textField.text length] + [string length] - range.length;
return (newLength > 10) ? NO : YES;
// unreachable!
So you are just checking the length but not whether the input is numerical. Change this line:
return (newLength > 10) ? NO : YES;
with this one:
if (newLength > 10) return NO;
and it should work. You can also optionally change this:
[NSCharacterSet characterSetWithCharactersInString:#"0123456789"]
with this:
[NSCharacterSet decimalDigitCharacterSet]