NSNumberFormatter unable to allow numbers to start with a 0 - objective-c

So I'm attempting to automatically add slashes between 2 digits when a user enters in their birthday, but for some reason when the birthday starts with a 0, the number formatter erases it and messes up the birthday. I've got my code below, could someone help me figure out how to do this? Thanks in advance!
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init] ;
[formatter setGroupingSeparator:#"/"];
[formatter setGroupingSize:2];
[formatter setUsesGroupingSeparator:YES];
[formatter setSecondaryGroupingSize:2];
NSString *num = textField.text ;
if(![num isEqualToString:#""])
{
num= [num stringByReplacingOccurrencesOfString:#"/" withString:#""];
NSString *str = [formatter stringFromNumber:[NSNumber numberWithDouble:[num doubleValue]]];
textField.text=str;
}

What you could do is the following:
Check the length of the string
If length mod 2 == 0 then add "/"
Log your string
I'm not saying this is recommended but it might help you a bit!
- (void)controlTextDidChange:(NSNotification *)obj{
NSString *num = [textField stringValue] ;
if (num.length%2==0)
{
NSString *someText = [NSString stringWithFormat: #"%#/ ", num];
num = someText;
}
textField.stringValue = num;
}

Something like this may help:
NSMutableString *string = #"YOUR TEXTFIELD TEXT";
NSString *lastString = [string substringWithRange:NSMakeRange(string.length-2, 1)];
if ([lastString isEqualToString:#"/"]) {
return;
}
if (string.length == 2 || string.length == 5) {
[string appendString:#"/"];
}

Related

how to convert arabic number to english number

I could convert English numbers to Arabic numbers in Xcode. but now I want to convert Arabic/Persian numbers to English numbers in iOS ...
Please guide me about this...
This is my code for conversion (English to Arabic) :
- (NSString*)convertEnNumberToFarsi:(NSString*)number {
NSString *text;
NSDecimalNumber *someNumber = [NSDecimalNumber decimalNumberWithString:number];
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
NSLocale *gbLocale = [[NSLocale alloc] initWithLocaleIdentifier:#"fa"];
[formatter setLocale:gbLocale];
text = [formatter stringFromNumber:someNumber];
return text;
}
Try this, I hope this helps you :
NSString *NumberString = #"۸۸۸";
NSNumberFormatter *Formatter = [[NSNumberFormatter alloc] init];
NSLocale *locale = [NSLocale localeWithLocaleIdentifier:#"EN"];
[Formatter setLocale:locale];
NSNumber *newNum = [Formatter numberFromString:NumberString];
if (newNum) {
NSLog(#"%#", newNum);
}
//print in console 888
You must take care of not only Persian numbers, but also Arabic ones.
Use the below functions/methods to do so:
// Convert string From English numbers to Persian numbers
+(NSString *) convertToPersianNumber:(NSString *) string {
NSNumberFormatter *formatter = [NSNumberFormatter new];
formatter.locale = [NSLocale localeWithLocaleIdentifier:#"fa"];
for (NSInteger i = 0; i < 10; i++) {
NSNumber *num = #(i);
string = [string stringByReplacingOccurrencesOfString:num.stringValue withString:[formatter stringFromNumber:num]];
}
return string;
}
// Convert string From Arabic/Persian numbers to English numbers
+(NSString *) convertToEnglishNumber:(NSString *) string {
NSNumberFormatter *formatter = [NSNumberFormatter new];
formatter.locale = [NSLocale localeWithLocaleIdentifier:#"fa"];
for (NSInteger i = 0; i < 10; i++) {
NSNumber *num = #(i);
string = [string stringByReplacingOccurrencesOfString:[formatter stringFromNumber:num] withString:num.stringValue];
}
formatter.locale = [NSLocale localeWithLocaleIdentifier:#"ar"];
for (NSInteger i = 0; i < 10; i++) {
NSNumber *num = #(i);
string = [string stringByReplacingOccurrencesOfString:[formatter stringFromNumber:num] withString:num.stringValue];
}
return string;
}
Follow the same. Just replace your locale identifier with "en".

NSNumberFormatter currency remove trailing zeros

I want to format prices like 45.50 but I don't want prices like 45.00. How can I avoid this?
I did it this way:
NSNumber *amount = #(50.5);
NSNumberFormatter *currencyFormat = [[NSNumberFormatter alloc] init];
[currencyFormat setNumberStyle:NSNumberFormatterCurrencyStyle];
[currencyFormat setLocale:[NSLocale currentLocale]];
if (trunc(amount.floatValue) == amount.floatValue) {
[currencyFormat setMaximumFractionDigits:0];
} else {
[currencyFormat setMaximumFractionDigits:2];
}
NSLog(#"%#", [currencyFormat stringFromNumber:amount]);
I like this solution for its simplicity. Output will be $50.50. And for amount = #(50.0) will be $50
Do this:
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
[formatter setNumberStyle:NSNumberFormatterDecimalStyle];
[formatter setMaximumFractionDigits:2];
[formatter setRoundingMode: NSNumberFormatterRoundUp];
NSString *numberString = [formatter stringFromNumber:[NSNumber numberWithFloat:22.368511]];
NSLog(#"Result...%#",numberString);//Result 22.37
Now trail unwanted like this:
NSString* CWDoubleToStringWithMax2Decimals(double d) {
NSString* s = [NSString stringWithFormat:#"%.2f", d];
NSCharacterSet* cs = [NSCharacterSet characterSetWithCharacterInString:#"0."];
NSRange r = [s rangeOfCharacterInSet:cs
options:NSBackwardsSearch | NSAnchoredSearch];
if (r.location != NSNotFound) {
s = [s substringToIndex:r.location];
}
return s;
}
If you're just after a very quick and dirty hack . . .
// Get the price as a string
NSString *priceString = [NSString stringWithFormat:#"%2.2f", priceFloat];
// Trim if needed
if ([priceString hasSuffix:#".00"])
priceString = [priceString substringToIndex:priceString.length-3];
NB This method won't work for localised content i.e. In Europe the decimal separator is a comma so you will see 45,00, not 45.00.
float myOriginalPrice = 45.50;
CGFloat mod = fmod(myOriginalPrice, 1);
if (mod == 0){
mod = (int)myOriginalPrice;
NSLog(#"%.0f", mod);
} else {
NSLog(#"%f", myOriginalPrice);
}
INPUT : 12.74 OR 12.745
NSString *inputString=[NSString string];
inputString=[NSString stringWithFormat:#"%.4g",12.74f];
NSLog(#"inputString : %# \n\n",inputString);
OUTPUT:
inputString : 12.74
INPUT : 12.00 OR 12.000
NSString *inputString=[NSString string];
inputString=[NSString stringWithFormat:#"%.4g",12.00f];
NSLog(#"inputString : %# \n\n",inputString);
OUTPUT:
inputString : 12
UPDATED ANSWER: for his comment question
INPUT:12.30
i assume here he is going to show this value in some UI like UILabel,.....Not For Calculation.
NSString *inputString=[NSString string];
inputString=[NSString stringWithFormat:#"%.4g",12.30f];
NSArray *arr=[inputString componentsSeparatedByString:#"."];
if ([arr count] >= 2) {
NSString *secondStr=[arr objectAtIndex:1];
if ([secondStr length]<2) {
inputString=[NSString stringWithFormat:#"%#0",inputString];
}
}
NSLog(#"inputString : %# \n\n",inputString);
OUTPUT:
inputString : 12.30

How can i display the number in such a format?

I am displaying a number in textfield. Which displays the number as "1234" but i want to display it as in format of "1,234" if i enter another large number which displays as "12345" but i want to display it as "12,345" if i enter 123456 which has to display as "123,456" . How do I format this number in desired format?
-(void)clickDigit:(id)sender
{
NSString * str = (NSString *)[sender currentTitle];
NSLog(#"%#",currentVal);
if([str isEqualToString:#"."]&& !([currentVal rangeOfString:#"."].location == NSNotFound) )
{
return;
}
if ([display.text isEqualToString:#"0"])
{
currentVal = str;
[display setText:currentVal];
}
else if([currentVal isEqualToString:#"0"])
{
currentVal=str;
[display setText:currentVal];
}
else
{
if ([display.text length] <= MAXLENGTH)
{
currentVal = [currentVal stringByAppendingString:str];
NSLog(#"%#",currentVal);
[display setText:currentVal];
}
currentVal=display.text;
}
}
This is the code i am using to display the number in textfield.
EDIT: I Changed my code into the following but still don't get the number correctly formatted:
if ([display.text length] <= MAXLENGTH) {
currentVal = [currentVal stringByAppendingString:str];
NSNumberFormatter * myNumFormatter = [[NSNumberFormatter alloc] init];
[myNumFormatter setNumberStyle:NSNumberFormatterDecimalStyle];
NSNumber *tempNum = [myNumFormatter numberFromString:currentVal];
NSLog(#"My number is %#",tempNum);
[display setText:[tempNum stringValue]];
currentVal=display.text;
}
You can do it like this:
int myInt = 12345;
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
formatter.numberStyle = NSNumberFormatterDecimalStyle;
NSNumber *number = [NSNumber numberWithInt:myInt];
NSLog(#"%#", [formatter stringFromNumber:number]); // 12,345
Edit
You didn't implement this correctly, the key is to obtain the string representation of the number using [formatter stringFromNumber:number], but you didn't do that. So change your code into:
currentVal = [currentVal stringByAppendingString:str];
NSNumberFormatter * myNumFormatter = [[NSNumberFormatter alloc] init];
[myNumFormatter setNumberStyle:NSNumberFormatterDecimalStyle];
NSNumber *tempNum = [myNumFormatter numberFromString:currentVal];
NSLog(#"My number is %#",tempNum);
[display setText:[myNumFormatter stringFromNumber:tempNum]]; // Change this line
currentVal=display.text;
NSLog(#"My formatted number is %#", currentVal);
First, read through the list of methods on the NSNumberFormatter reference page. After doing that, you'll probably realize that you need to use the -setHasThousandSeparators: method to turn on the thousand separators feature. You can also use the -setThousandSeparator: method to set a custom separator, though you probably won't need to do that.

NSNumberFormatter not allowing decimal input

If I enter a decimal point '.' into my UITextField, the number formatter called does not recognise the decimal point and continues as if the decimal point has not been entered. I.e If I entered 200.9, the decimal point would not show up in the textfield and the text of the textfield would be 2009.
I want to limit the number of digits after the decimal point to 2 as I believe I am doing below. Please can you tell me what I am doing to cause this?
- (BOOL) textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
BOOL isDeleting = [textField.text substringWithRange:range].length > string.length;
int index = [textFields indexOfObject:textField];
NSString *input;
if (isDeleting == NO)
input = [textField.text stringByAppendingString:string];
else {
NSMutableString *str = [textField.text mutableCopy];
[str deleteCharactersInRange:range];
input = [[str copy] autorelease];
[str release];
}
if ([input isEqualToString:#"£"] || ([input isEqualToString:#""] && index != 1)) {
[textField setText:#"£"];
}
else {
if (index != 1)
[textField setText:[self numberFormattedString:input]];
else
[textField setText:input];
}
return NO;
}
- (NSString *) numberFormattedString:(NSString *)str {
str = [str stringByReplacingOccurrencesOfString:#"£" withString:#""];
str = [str stringByReplacingOccurrencesOfString:#"," withString:#""];
NSNumberFormatter *formatter = [[[NSNumberFormatter alloc] init] autorelease];
[formatter setNumberStyle:NSNumberFormatterCurrencyStyle];
NSLocale *locale = [[NSLocale alloc] initWithLocaleIdentifier:#"en-UK"];
[formatter setLocale:locale];
[locale release];
[formatter setAllowsFloats:YES];
[formatter setMaximumFractionDigits:3];
[formatter setMinimumFractionDigits:0];
[formatter setDecimalSeparator:#"."];
return [formatter stringFromNumber:[NSNumber numberWithFloat:[str floatValue]]];
}
TIA.
Let's say you enter the number 100 and then a decimal point. When numberFormattedString is called with the string £100., it's going to get rid of the £, and str will contain the string 100. which [str floatValue] converts to the float value 100, and finally your number formatter spits it back out as the string £100 without any decimal point. So basically [str floatValue] is killing your decimal point.
One solution is to check for when you get the decimal point as your replacement string in the text field delegate method, and skip calling numberFormattedString in that case. Then when the user enters the next digit, you can carry on calling numberFormattedString, and the conversion should happen correctly. You'll just have to make sure that the user can only enter one decimal point.
EDIT: I just realized that my suggested solution still won't work if you enter a 0 after the decimal point (e.g. 100.0), but I'm sure there is a minor tweak that you can figure out to solve that.
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
NSCharacterSet *numSet = [NSCharacterSet characterSetWithCharactersInString:#"0123456789."];
NSString *newString = [textField.text stringByReplacingCharactersInRange:range withString:string];
int charCount = [newString length];
if ([newString rangeOfCharacterFromSet:[numSet invertedSet]].location != NSNotFound
|| [string rangeOfString:#"."].location != NSNotFound
|| charCount > 15) {
return NO;
}
// if (charCount == 4 || charCount == 9 || charCount==13) {
// newString = [newString stringByAppendingString:#"."];
// }
NSLog(#"IN method");
textField.text = newString;
return NO;
}

How to round Decimal values in Objective C

This may be a easy question but i am not able to find the logic.
I am getting the values like this
12.010000
12.526000
12.000000
12.500000
If i get the value 12.010000 I have to display 12.01
If i get the value 12.526000 I have to display 12.526
If i get the value 12.000000 I have to display 12
If i get the value 12.500000 I have to display 12.5
Can any one help me out please
Thank You
Try this :
[NSString stringWithFormat:#"%g", 12.010000]
[NSString stringWithFormat:#"%g", 12.526000]
[NSString stringWithFormat:#"%g", 12.000000]
[NSString stringWithFormat:#"%g", 12.500000]
float roundedValue = 45.964;
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
[formatter setMaximumFractionDigits:2];
[formatter setRoundingMode: NSNumberFormatterRoundUp];
NSString *numberString = [formatter stringFromNumber:[NSNumber numberWithFloat:roundedValue]];
NSLog(numberString);
[formatter release];
Some modification you may need-
// You can specify that how many floating digit you want as below
[formatter setMaximumFractionDigits:4];//2];
// You can also round down by changing this line
[formatter setRoundingMode: NSNumberFormatterRoundDown];//NSNumberFormatterRoundUp];
Reference: A query on StackOverFlow
Obviously taskinoor's solution is the best, but you mentioned you couldn't find the logic to solve it... so here's the logic. You basically loop through the characters in reverse order looking for either a non-zero or period character, and then create a substring based on where you find either character.
-(NSString*)chopEndingZeros:(NSString*)string {
NSString* chopped = nil;
NSInteger i;
for (i=[string length]-1; i>=0; i--) {
NSString* a = [string substringWithRange:NSMakeRange(i, 1)];
if ([a isEqualToString:#"."]) {
chopped = [string substringToIndex:i];
break;
} else if (![a isEqualToString:#"0"]) {
chopped = [string substringToIndex:i+1];
break;
}
}
return chopped;
}