TextField:shouldChangeCharactersInRange:replacementString: return trap! - iphone

Im calling UITableViewCell delegate method TextField:shouldChangeCharactersInRange:replacementString: on a custom cell that has four UITextFields and what is happening once maxlength is reached on one of the fields it dose not let you enter any text in the other fields because its always returning "no" for that initial if statement thats being satisfied. any ideas on how to get around this?
I'm only testing on two fields at the moment. Thank you for any help in advance.
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
int regFieldOnelength = [regFieldOne.text length] ;
int regFieldTwolength = [regFieldTwo.text length] ;
if ((regFieldOnelength >= MAXLENGTH && ![string isEqualToString:#""]) || (regFieldTwolength >= MAXLENGTH && ![string isEqualToString:#""])) {
if(regFieldOne.text = [regFieldOne.text substringToIndex:MAXLENGTH]){
return NO;
}
if(regFieldTwo.text = [regFieldTwo.text substringToIndex:MAXLENGTH]){
return NO;
}
}
return YES;
}

Why are you using booth the text field, Instead use the current text field that is being edited
-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
int currentTxtLen = [textField.text length] ;
if (currentTxtLen >= MAXLENGTH && ![string isEqualToString:#""]) {
return NO;
}
return YES;
}

Can you try
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
int regFieldOnelength = [regFieldOne.text length] ;
int regFieldTwolength = [regFieldTwo.text length] ;
if((textField == regFieldOne) ||(textField == regFieldTwo)) {
if ((regFieldOnelength >= MAXLENGTH && ![string isEqualToString:#""]) || (regFieldTwolength >= MAXLENGTH && ![string isEqualToString:#""])) {
if(regFieldOne.text = [regFieldOne.text substringToIndex:MAXLENGTH]){
return NO;
}
if(regFieldTwo.text = [regFieldTwo.text substringToIndex:MAXLENGTH]){
return NO;
}
}
return YES;
}
else {
return YES;
}
}

Related

How to Append a Special Character after every 3 characters in UITextField Ex: (123-12346) like '-' i did it but issue while Clear

I am getting Phone card number form user in UI text field. The format of number is like
123-4567-890
I want that as user types 123 automatically - is inserted in UITextField same after 4567 - and so on.
I Did it using following code in UITextField delegate method:
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string;
{
NSLog(#"***** %d",textField.text.length);
if(textField.text.length == 3)
{
textField.text = [textField.text stringByAppendingString:#"-"];
}
return YES;
}
But the Problem raised while clear the text, When we start clearing.
Last 3 digits 890 clears and then - addded, we cleared it and again added and soooo on so clearing stop at
We clear all the text at a time using
textField.clearButtonMode = UITextFieldViewModeWhileEditing; //To clear all text at a time
But our requirement is user must delete one character at a time.
How to achieve it?
During clearing replacementString should be empty #"". So replacement string should be checked also in addition to length check. Like this:
if (textField.text.length == 3 && ![string isEqualToString:#""]) {
// append -
}
USE: I have seen this somewhere in this forum, It worked for me
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
NSString *filter = #"###-####-###";
if(!filter) return YES;
NSString *changedString = [textField.text stringByReplacingCharactersInRange:range withString:string];
if(range.length == 1 && string.length < range.length && [[textField.text substringWithRange:range] rangeOfCharacterFromSet:[NSCharacterSet characterSetWithCharactersInString:#"0123456789"]].location == NSNotFound)
{
NSInteger location = changedString.length-1;
if(location > 0)
{
for(; location > 0; location--)
{
if(isdigit([changedString characterAtIndex:location]))
break;
}
changedString = [changedString substringToIndex:location];
}
}
textField.text = filteredStringFromStringWithFilter(changedString, filter);
return NO;
}
NSString *filteredStringFromStringWithFilter(NSString *string, NSString *filter)
{
NSUInteger onOriginal = 0, onFilter = 0, onOutput = 0;
char outputString[([filter length])];
BOOL done = NO;
while(onFilter < [filter length] && !done)
{
char filterChar = [filter characterAtIndex:onFilter];
char originalChar = onOriginal >= string.length ? '\0' : [string characterAtIndex:onOriginal];
switch (filterChar) {
case '#':
if(originalChar=='\0')
{
done = YES;
break;
}
if(isdigit(originalChar))
{
outputString[onOutput] = originalChar;
onOriginal++;
onFilter++;
onOutput++;
}
else
{
onOriginal++;
}
break;
default:
outputString[onOutput] = filterChar;
onOutput++;
onFilter++;
if(originalChar == filterChar)
onOriginal++;
break;
}
}
outputString[onOutput] = '\0';
return [NSString stringWithUTF8String:outputString];
}

Decimal style improvement objective c calculator

I'm doing the calculator tutorial for iOS and I've done some research for doing the decimal style. So far on my research, I've gone through this code below
- (IBAction)digitPressed:(UIButton *)sender {
NSString *digit = sender.currentTitle;
NSString *decimal = #".";
BOOL decimalAlreadyEntered = [self.display.text rangeOfString:decimal].location == NSNotFound ? NO : YES;
if (self.userIsInTheMiddleOfEnteringANumber) {
if (([digit isEqual:decimal] && !decimalAlreadyEntered) || !([digit isEqual:decimal])) {
[self.display setText:[[self.display text] stringByAppendingString:digit]];
}
}
else if ([self.display.text isEqual:#"0"] && digit == decimal){
[self.display setText:[[self.display text] stringByAppendingString:digit]];
self.userIsInTheMiddleOfEnteringANumber = YES;
}
else {
[self.display setText:digit];
self.userIsInTheMiddleOfEnteringANumber = YES;
}
}
This code helped me to prevent multiple decimal points being pressed by the user, and limit it only to one (as in 2.09). Cool! However during the start of the app, when I press on the decimal point and pressed on a number, say 1, the label will only display ( .1) instead of (0.1) . Any help for the improvement is much appreciated :)
In - (BOOL) textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string you can check whether first value is "." then replace text value by "0.", whatever user has entered.And perform this check only when textfield value is ".something".
- (BOOL) textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
NSString *symbol = [[NSLocale currentLocale] objectForKey:NSLocaleDecimalSeparator];
if (range.location == 0 && [string isEqualToString:symbol]) {
// decimalseparator is first
textField.text = [NSString stringWithFormat:#"0%#",textField.text];
return YES;
}
}

UITextField: backspace not working

I have an issue with UITextField's validation. I want to validate the UITextField's text-length to be 5(fixed).
my code :
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
if(textField==codeTxt)
{
NSCharacterSet *unacceptedInput = [[NSCharacterSet characterSetWithCharactersInString:NUMBERS]invertedSet] ;
if ([[string componentsSeparatedByCharactersInSet:unacceptedInput] count] > 1)
return NO;
else if ([codeTxt.text length] >= 5])
return NO;
else
return YES;
}
}
this code works fine. It validates and ignores rest of the text(more thn 5).
my problem :
When I press Delete(Backspace), nothing happens !!! the text remains the same. delete(Backspace) does not work.
what could be the problem ?
Thanks...
put this condition at first statement in shouldChangeCharactersInRange method
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
if([string length]==0)
{
return YES;
}
if(textField==codeTxt)
{
NSCharacterSet *unacceptedInput = [[NSCharacterSet characterSetWithCharactersInString:NUMBERS]invertedSet] ;
if ([[string componentsSeparatedByCharactersInSet:unacceptedInput] count] > 1)
return NO;
else if ([codeTxt.text length] >= 5])
return NO;
else
return YES;
}
}
Your only checking the length of the current text in the field. This method gets called before the text changes, so you need to check the replacementString's length first, then check the textField's text length.
Try this:
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
if (textField == codeTxt) {
// NSCharacterSet *unacceptedInput = [[NSCharacterSet characterSetWithCharactersInString:NUMBERS] invertedSet];
// if ([[string componentsSeparatedByCharactersInSet:[unacceptedInput count]] > 1) {
if ([[string componentsSeparatedByCharactersInSet:[[[NSCharacterSet characterSetWithCharactersInString:NUMBERS] invertedSet] autorelease]] count] > 1) {
return NO;
} else if ([string length] < 5) {
return YES;
} else if ([codeTxt.text length] >= 5]) {
return NO;
} else {
return YES;
}
}
}
Edit:
Checking the textField's length probably isn't even necessary after doing [codeTxt.text length] >= 5] since this will prevent the textField's length from ever going above 4 anyway.
Actually, you would need to check it since the default is to return YES;.
Probably needs to be <= 5
} else if ([string length] <= 5) {
return YES;
}
Instead of < 5 too
} else if ([string length] < 5) {
return YES;
}
I got the solution
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
if(textField==codeTxt)
{
NSCharacterSet *unacceptedInput = [[NSCharacterSet characterSetWithCharactersInString:NUMBERS]invertedSet] ;
NSLog(#"textfield character validation method called");
NSLog(#"%d",[codeTxt.text length]);
if ([[string componentsSeparatedByCharactersInSet:unacceptedInput] count] > 1)
return NO;
else if ([codeTxt.text length] >= 5 && ![string isEqual:#""])
return NO;
else
return YES;
}
}

Validate against empty UITextField?

What is the value of a UITextField when it is empty? I can't seem to get this right.
I've tried (where `phraseBox' it the name of the said UITextField
if(phraseBox.text != #""){
and
if(phraseBox.text != nil){
What am I missing?
// Check to see if it's blank
if([phraseBox.text isEqualToString:#""]) {
// There's no text in the box.
}
// Check to see if it's NOT blank
if(![phraseBox.text isEqualToString:#""]) {
// There's text in the box.
}
found this at apple discussions when searching for the same thing,thought ill post it here too.
check the length of the string :
NSString *value = textField.text;
if([value length] == 0) {
}
or optionally trim whitespaces from it before validation,so user cannot enter spaces instead.works well for usernames.
NSString *value = [textField.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
if([value length] == 0) {
// Alert the user they forgot something
}
Try following code
textField.text is a string value so we are checking it like this
if([txtPhraseBox.text isEqualToString:#""])
{
// There's no text in the box.
}
else
{
NSLog(#"Text Field Text == : %# ",txtPhraseBox.text);
}
-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{
NSString *fullText = [textField.text stringByAppendingString:string];
if ((range.location == 0) && [self isABackSpace:string]) {
//the textFiled will be empty
}
return YES;
}
-(BOOL)isABackSpace:(NSString*)string {
NSString* check =#"Check";
check = [check stringByAppendingString:string];
if ([check isEqualToString:#"Check"]) {
return YES;
}
return NO;
}
Use for text field validation:
-(BOOL)validation{
if ([emailtextfield.text length] <= 0) {
[UIAlertView showAlertViewWithTitle:AlertTitle message:AlertWhenemailblank];
return NO; }
return YES;}
Actually, I ran into slight problems using Raphael's approach with multiple text fields. Here's what I came up with:
if ((usernameTextField.text.length > 0) && (passwordTextField.text.length > 0)) {
loginButton.enabled = YES;
} else {
loginButton.enabled = NO;
}
Validation against empty UITextfield. if you don't want that UITextField should not accept blank white spaces. Use this code snippet:
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
NSString *resultingString = [textField.text stringByReplacingCharactersInRange: range withString: string];
NSCharacterSet *whitespaceSet = [NSCharacterSet whitespaceCharacterSet];
if ([resultingString rangeOfCharacterFromSet:whitespaceSet].location == NSNotFound) {
return YES;
} else {
return NO;
}
}

Set UITextField Maximum Length [duplicate]

This question already has answers here:
Set the maximum character length of a UITextField
(46 answers)
Closed 10 years ago.
Is there any way to set the maximum length on a UITextField?
Something like the MAXLENGTH attribute in HTML input fields.
This works correctly with backspace and copy & paste:
#define MAXLENGTH 10
- (BOOL)textField:(UITextField *) textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
NSUInteger oldLength = [textField.text length];
NSUInteger replacementLength = [string length];
NSUInteger rangeLength = range.length;
NSUInteger newLength = oldLength - rangeLength + replacementLength;
BOOL returnKey = [string rangeOfString: #"\n"].location != NSNotFound;
return newLength <= MAXLENGTH || returnKey;
}
UPDATE: Updated to accept the return key even when at MAXLENGTH. Thanks Mr Rogers!
UPDATE
I cannot delete this answer because it is the accepted one, but it was not correct. Here is the correct code, copied from TomA below:
#define MAXLENGTH 10
- (BOOL)textField:(UITextField *) textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
NSUInteger oldLength = [textField.text length];
NSUInteger replacementLength = [string length];
NSUInteger rangeLength = range.length;
NSUInteger newLength = oldLength - rangeLength + replacementLength;
BOOL returnKey = [string rangeOfString: #"\n"].location != NSNotFound;
return newLength <= MAXLENGTH || returnKey;
}
ORIGINAL
I think you mean UITextField. If yes, then there is a simple way.
Implement the UITextFieldDelegate protocol
Implement the textField:shouldChangeCharactersInRange:replacementString: method.
That method gets called on every character tap or previous character replacement. in this method, you can do something like this:
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
if ([textField.text length] > MAXLENGTH) {
textField.text = [textField.text substringToIndex:MAXLENGTH-1];
return NO;
}
return YES;
}
A better function which handles backspaces correctly and limits the characters to the supplied length limit is the following:
#define MAXLENGTH 8
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
int length = [textField.text length] ;
if (length >= MAXLENGTH && ![string isEqualToString:#""]) {
textField.text = [textField.text substringToIndex:MAXLENGTH];
return NO;
}
return YES;
}
Cheers!
This code limits the text while also allowing you enter characters or paste anywhere into the text. If the resulting text would be too long it changes the characters in the range and truncates the resulting text to the limit.
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
NSUInteger newLength = [textField.text length] - range.length + [string length];
if (newLength >= MAXLENGTH) {
textField.text = [[textField.text stringByReplacingCharactersInRange:range withString:string] substringToIndex:MAXLENGTH];
return NO;
}
return YES;
}
I think this code would do the trick:
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range
replacementString:(NSString*)string
{
if (range.location >= MAX_LENGTH)
return NO;
return YES;
}
With this delegate method you can prevent the user to add more characters than MAX_LENGTH to your text field and the user should be allowed to enter backspaces if needed.
For me this did the magic:
if (textField.text.length >= 10 && range.length == 0)
return NO;
return YES;
this is how i resolved that problem. When max limit is reached it wont try to add more... you will only be able to remove chars
#define MAX_SIZE ((int) 5)
...
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
if ([textField.text length] >= MAX_SIZE && ![string isEqualToString:#""]) {
return NO;
}
return YES;
}
I think there's no such property.
But the text you assign to the UILabel has to be an NSString. And before you assign this string to the UILabel's text property you can for example use the following method of NSString to crop the string at a given index (your maxlength):
- (NSString *)substringToIndex:(NSUInteger)anIndex
This is similar to coneybeare's answer, but now the text field can contain a maximum of MAXLENGTH symbols:
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
if ([textField.text length] > MAXLENGTH - 1) {
textField.text = [textField.text substringToIndex:MAXLENGTH];
return NO;
}
return YES;
}
You have to be aware of the location the text is placed in as well as the length of text being added (in case they're pasting more than one character). The pattern between these with respect to max length is that their sum should never exceed the max length.
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
NSInteger locationAndStringLengthSum = range.location + [string length];
if ([textField isEqual:_expirationMonthField]) {
if (locationAndStringLengthSum > EXP_MONTH_FIELD_MAX_CHAR_LENGTH) {
return NO;
}
}
else if ([textField isEqual:_expirationYearField]) {
if (locationAndStringLengthSum > EXP_YEAR_FIELD_MAX_CHAR_LENGTH) {
return NO;
}
}
else if ([textField isEqual:_securityCodeField]) {
if (locationAndStringLengthSum > SECURITY_FIELD_MAX_CHAR_LENGTH) {
return NO;
}
}
else if ([textField isEqual:_zipCodeField]) {
if (locationAndStringLengthSum > ZIP_CODE_MAX_CHAR_LENGTH) {
return NO;
}
}
return YES;
}
You need to assign delegate on ViewDidLoad
TextFieldname.delegate=self