PDA

View Full Version : Validation on UItextField




rupesh.swami
Apr 1, 2009, 07:19 AM
hi all,
i am new to iPhone programming
in my UIview, there are some UITextFields. i want to input only numbers and a dot (".") one time. How can i achive this task
i already set the keyboard to numeric but keyboard facilitate to switch between numeric and alphabetic keys.



iphonedevelop18
Apr 1, 2009, 09:09 AM
so you want to type in a decimal??

Use the keyboard type numbers and punctuation keyboard type.

rupesh.swami
Apr 2, 2009, 04:17 AM
so you want to type in a decimal??

Use the keyboard type numbers and punctuation keyboard type.

i already set keyboard type numbers and punctuation but keyboard allows us to type punctuation symbol and we can also change it to alphabetic keyboard.

i use following delegate but this does not allow to type in any key(numeric, alphabetic etc)

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
NSCharacterSet *nonNumberSet = [[NSCharacterSet characterSetWithRange:NSMakeRange('0',10)] invertedSet];
NSString *trimmed = [textField.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
BOOL isNumeric = [trimmed length] > 0 && [trimmed rangeOfCharacterFromSet:nonNumberSet].location == NSNotFound;
return isNumeric;
}

what should i do ?
please help me . i am new to iPhone programming

rupesh.swami
Apr 2, 2009, 06:39 AM
finally i write delegate which check each key pressed with keyboard and return appropriate result (numeric character with single decimal ). delegate code is following

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
BOOL isNumeric=FALSE;
if ([string length] == 0)
{
isNumeric=TRUE;
}
else
{

if ( [string compare:[NSString stringWithFormat:@"%d",0]]==0 || [string compare:[NSString stringWithFormat:@"%d",1]]==0
|| [string compare:[NSString stringWithFormat:@"%d",2]]==0 || [string compare:[NSString stringWithFormat:@"%d",3]]==0
|| [string compare:[NSString stringWithFormat:@"%d",4]]==0 || [string compare:[NSString stringWithFormat:@"%d",5]]==0
|| [string compare:[NSString stringWithFormat:@"%d",6]]==0 || [string compare:[NSString stringWithFormat:@"%d",7]]==0
|| [string compare:[NSString stringWithFormat:@"%d",8]]==0 || [string compare:[NSString stringWithFormat:@"%d",9]]==0)
{
isNumeric=TRUE;
}
else
{
unichar mychar=[string characterAtIndex:0];
if (mychar==46)
{
int i;
for (i=0; i<[textField.text length]; i++)
{

unichar c = [textField.text characterAtIndex: i];
if(c==46)
return FALSE;
}

isNumeric=TRUE;
}
}
}

return isNumeric;
}

Above code is wrost case for get proper result. Can i improve this code ?
Please suggest

iphonedevelop18
Apr 2, 2009, 11:36 AM
One thing I caught was all those or statements, you can make this much more efficient by making it check int x instead of making all those or statements seeing if it equals a number 1 - 9, using a while loop.


int x;
while (x <= 10){
if ( [string compare:[NSString stringWithFormat:@"%i",x]]==0) {
isNumeric = TRUE;
}
else {
do all that stuff
}
x = x + 1;
}



So what this does is when x is less than 10 it will check if your input equals x ( number 1-9) it will set isNumeric to true. It will then add one to x so that next time it will change numbers so it checks every number 1-9.

Otherwise code looks pretty good to me.

Hope this helps.

rupesh.swami
Apr 3, 2009, 10:42 AM
what about allow only single decimal symbol ('.')?l

dejo
Apr 3, 2009, 10:46 AM
what about allow only single decimal symbol ('.')?l
Maybe set a flag when they type the first one and then ignore any other ones after that?

eddietr
Apr 3, 2009, 05:58 PM
It seems as though you just want to limit the user to decimal numbers? If so, another option you might consider is just converting the string to a decimal number and if you get a valid number then you have a valid string.

The only catch is that NSNumberFormatter will allow any characters after the number. So "1.12aaaa" will still return 1.12 as the number. To deal with that, you will need to check the actual range (within the string) that was converted to a number. This will also prevent the user from inserting two decimal points.

The big advantage is that you can configure the formatter with extra constraints like minimum/maximum number, or maximum number of digits after the decimal place, etc. Lots of options there that you won't have to code yourself.

Anyway, easier done than said, so it would look something like the following:


- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string; {

NSNumber* candidateNumber; // This is the number we will try to extract from the string

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])) {

NSLog(@"Not a good number"); // Probably should tell the user something here
return NO;
}

else return YES;
}


Of course you will need to set up the formatter somewhere in your delegate such as awakeFromNib or your initializer (and dispose of it later):


numberFormatter = [[NSNumberFormatter alloc] init];
[numberFormatter setNumberStyle:NSNumberFormatterDecimalStyle];