xcode 4.2.1 - limiting character length in TextField - iphone

I have been trying to limit a textField by many codes available out there in the internet but with no luck.
I have added UIViewController<UITextFieldDelegate> in my header file
and textField.delegate = self; in my viewDidLoad
and implemented the following fundtion in my .m file:
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
NSString *newString = [textField.text stringByReplacingCharactersInRange:range withString:string];
return !([newString length] > 5);
}
this stil does not limit my text field. any idea?

Do it as following as it has been the exact duplicate of this
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
NSUInteger newLength = [textField.text length] + [string length] - range.length;
return (newLength > 5) ? NO : YES;
}

The replacement string is just the 1 character that was pressed, not the whole string so you need to add It to the current textfield.text before counting.
Your count is probably always 1 (or more if pasting a word)

I implement this in my code and it works:
This code eliminate all the letters only accept numbers, but like I delete the character, you could delete everything that its over length 5 and it keeps a nice effect that appears and disappears
- (void)textFieldDidBeginEditing:(UITextField *)textField {
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(textChanged:) name:UITextFieldTextDidChangeNotification object:textField];
}
- (void)textChanged:(NSNotification *)textField {
NSString *text = [[textField object] text];
NSString *last = [text substringFromIndex:[text length] -1];
NSArray *accept = [NSArray arrayWithObjects:#"0", #"1", #"2", #"3", #"4", #"5", #"6", #"7" , #"8", #"9", #".", nil];
for (int i=0; i<[accept count]; i++) {
NSLog(#"%#", [accept objectAtIndex:i]);
if (![last isEqualToString:[accept objectAtIndex:i]]) {
[[textField object] setText:[text substringToIndex:[text length]-1]];
}
}
}

Related

Local search in NSMutalbleArray

I want to search in NSMutalbleArray, my code is :
arrCelebs=[[NSMutableArray alloc] initWithObjects:#"Test 1",#"Test 2",#"Test 42",#"Test 5", nil];
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
NSString *arrString1 = txtSearch.text;
NSRange tmprange;
for(NSString *string in arrCelebs) {
tmprange = [arrString1 rangeOfString:string];
if (tmprange.location != NSNotFound) {
NSLog(#"String found");
break;
}
}
return YES;
}
if i enter "t" then it search all the data and i want to add it another array. for display in tableview.
You can use the power of NSPredicate
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SELF BEGINSWITH[c] %#", textField.text];
NSArray *filteredArray = [arrCelebs filteredArrayUsingPredicate:predicate];
By using predicate you Can easily get the result efficiently.
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SELF beginswith[c] %#", txtSearch.text];
NSArray *ResultArray = [yourArray filteredArrayUsingPredicate:predicate];
return YES;
}
Try :
arr_NewArray = [[NSMutableArray alloc] init];
for (int i = 0; i < [arr_YourArrayToSearch count]; i++)
{
NSString *curString = [string lowercaseString];
NSString *curStringInArray = [[arr_YourArrayToSearch objectAtIndex:i]lowercaseString];
if (![curString rangeOfString:curStringSmall].location == NSNotFound)
{
[arr_NewArray addObject:[arr_YourArrayToSearch objectAtIndex:i]];
}
}
arr_NewArray will give you the array with data matched to your search string.
arrCelebs=[[NSMutableArray alloc] initWithObjects:#"Test 1",#"Test 2",#"Test 42",#"Test 5", nil];
_resultArray = [[NSMutableArray alloc] init];
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
NSString *arrString1 = txtSearch.text;
NSRange tmprange;
_resultArray = [[NSMutableArray alloc] init];
for(NSString *string in arrCelebs) {
tmprange = [arrString1 rangeOfString:string];
if (tmprange.location != NSNotFound) {
[_resultArray addObject:string];
}
}
return YES;
}
IF YOU work With UITableView then you cal also put this type of Logic.
Take Two NSMutableArray and add one array to another array in ViewDidLoad method such like,
self.listOfTemArray = [[NSMutableArray alloc] init]; // array no - 1
self.ItemOfMainArray = [[NSMutableArray alloc] initWithObjects:#"YorArrayList", nil]; // array no - 2
[self.listOfTemArray addObjectsFromArray:self.ItemOfMainArray]; // add 2array to 1 array
And Write following delegate Method of UISearchBar
- (BOOL) textFieldDidChange:(UITextField *)textField
{
NSString *name = #"";
NSString *firstLetter = #"";
if (self.listOfTemArray.count > 0)
[self.listOfTemArray removeAllObjects];
if ([searchText length] > 0)
{
for (int i = 0; i < [self.ItemOfMainArray count] ; i = i+1)
{
name = [self.ItemOfMainArray objectAtIndex:i];
if (name.length >= searchText.length)
{
firstLetter = [name substringWithRange:NSMakeRange(0, [searchText length])];
//NSLog(#"%#",firstLetter);
if( [firstLetter caseInsensitiveCompare:searchText] == NSOrderedSame )
{
// strings are equal except for possibly case
[self.listOfTemArray addObject: [self.ItemOfMainArray objectAtIndex:i]];
NSLog(#"=========> %#",self.listOfTemArray);
}
}
}
}
else
{
[self.listOfTemArray addObjectsFromArray:self.ItemOfMainArray ];
}
[self.tblView reloadData];
}
}
Output Show in your Consol.
This exact what you want...
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
NSMutableArray *resultAry = [[NSMutableArray alloc] init];
for(NSString *string in arrCelebs)
{
NSRange range = [string rangeOfString:textField.text options:NSCaseInsensitiveSearch];
if(range.location != NSNotFound)
{
[resultAry addObject:string];
}
}
yourTableAry=[resultAry mutableCopy];
[yourTable reloadData];
return YES;
}

how to validate textfield that allows only single decimal point in textfield?

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;
}

How to restrict user to type in textfield after typing some characters

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 to show single dot using custom Number pad in iphone?

i am creating custom NumberPad
if (([[[UIDevice currentDevice] systemVersion] doubleValue] >= 4.1)) {
inputBoxTextField.keyboardType = UIKeyboardTypeDecimalPad;
}
my problem is, i want to display dot only one time.
thanks in advance.
If you want to allow the user to enter only one dot, you can use the delegate method
-(BOOL) textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
And simply check if the textField already contains a dot.
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init];
[numberFormatter setNumberStyle:NSNumberFormatterDecimalStyle];
NSNumber* candidateNumber;
NSString* candidateString = [textField.text stringByReplacingCharactersInRange:range withString:string];
range = NSMakeRange(0, [candidateString length]);
[numberFormatter getObjectValue:&candidateNumber forString:candidateString range:&range error:nil];
if (([candidateString length] > 0) && (candidateNumber == nil || range.length < [candidateString length])) {
return NO;
}
else {
return YES; } }
I use the following code. Works perfectly for me and with less code.
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init];
[numberFormatter setNumberStyle:NSNumberFormatterDecimalStyle];
NSString *decimalSymbol = [numberFormatter decimalSeparator];
if(([textField.text rangeOfString:decimalSymbol].location != NSNotFound) &&
([string rangeOfString:decimalSymbol].location != NSNotFound)) {
return NO;
}
return YES;
}

Backspace not working when implementing shouldChangeCharactersInRange method - iPhone Dev

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);
}