Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

rupesh.swami

macrumors newbie
Original poster
Mar 9, 2009
29
0
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.
 

rupesh.swami

macrumors newbie
Original poster
Mar 9, 2009
29
0
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)

Code:
- (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

macrumors newbie
Original poster
Mar 9, 2009
29
0
finally i write delegate which check each key pressed with keyboard and return appropriate result (numeric character with single decimal ). delegate code is following

Code:
- (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

macrumors member
Feb 26, 2009
50
0
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.

Code:
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.
 

eddietr

macrumors 6502a
Oct 29, 2006
807
0
Virginia
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:

Code:
- (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):

Code:
numberFormatter = [[NSNumberFormatter alloc] init];
[numberFormatter setNumberStyle:NSNumberFormatterDecimalStyle];
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.