In my app, i have an amount field. It should accept only 6 digits BEFORE decimal point and any number of digits AFTER decimal point which will be rounded off to 2 digits. How to do this.? For Example, typing in 12345678 can be truncated to 123456 on clicking RETURN key.. Same way, 12345678.75 -> 123456 123456.456 -> 123456.46
This code should help.
double input = 12345678.75;
double output;
NSString *string = [NSString stringWithFormat:#"%lf", input];
int dotPosition = [string rangeOfString:#"."].location;
if(dotPosition == NSNotFound || dotPosition > 6)
{
output = [string substringToIndex:6].doubleValue;
}
else
{
output = round(input * 100) / 100;
}
UPD according to iPhoneDev's comment:
Previous part of code takes and returns double values.
Here is code whitch deals wiht strings:
NSString * input = #"123456.754";
NSString * output;
int dotPosition = [input rangeOfString:#"."].location;
if(dotPosition == NSNotFound || dotPosition > 6)
{
output = [input substringToIndex:6];
}
else
{
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
formatter.decimalSeparator = #".";
[formatter setRoundingMode: NSNumberFormatterRoundHalfUp];
[formatter setMaximumFractionDigits:2];
output = [formatter stringFromNumber:#(input.doubleValue)];
}
Use this code
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{
NSString* proposedString = [textField.text stringByReplacingCharactersInRange:range withString:string];
//if there is empty string return YES
if([proposedString length] == 0) {
return YES;
}
//create inverted set for appripriate symbols
NSCharacterSet *nonNumberSet = [[NSCharacterSet characterSetWithCharactersInString:#"0123456789.,"] invertedSet];
//if side symbols is trimmed by nonNumberSet - return NO
if([proposedString stringByTrimmingCharactersInSet:nonNumberSet].length != [proposedString length]) {
return NO;
}
if([[proposedString componentsSeparatedByCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:#"."]] count] > 2) {
return NO;
}
//finally check is ok, return YES
return YES;
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField{
NSArray *components = [textField.text componentsSeparatedByString:#"."];
// Below 6 & 2 are the range
NSString *leftString;
if ([[components objectAtIndex:0] length] > 6) {
leftString = [[components objectAtIndex:0] substringToIndex:6];
}
NSString *rightString;
if ([[components objectAtIndex:1] length] > 2) {
rightString = [[components objectAtIndex:1] substringToIndex:2];
}
[textField setText:[NSString stringWithFormat:#"%#.%#",leftString,rightString]];
[textField resignFirstResponder];
return YES;
}
double input = 123456.4645;
double output;
NSString *string = [NSString stringWithFormat:#"%lf", input];
int dotPosition = [string rangeOfString:#"."].location;
if(dotPosition == NSNotFound || dotPosition > 6)
{
output = [string substringToIndex:6].doubleValue;
}
else
{
double Rate_int = [input doubleValue];
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
[formatter setRoundingMode: NSNumberFormatterRoundHalfUp];
[formatter setMaximumFractionDigits:2];
NSString *numberString = [formatter stringFromNumber:[NSNumber numberWithDouble:Rate_int]];
output = [numberString doubleValue];
}
Related
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;
}
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;
}
In iPhone contacts tableview there is a cell called "phone", when user edit this cell phone number becomes in something like this: (251) 575-3621. How can I make this cell type?
Thanks..
- (BOOL)textField:(UITextField *)textField
shouldChangeCharactersInRange:(NSRange)range
replacementString:(NSString *)string {
NSUInteger currentLength = textField.text.length;
NSCharacterSet *numbers = [NSCharacterSet decimalDigitCharacterSet];
if (range.length == 1) {
return YES;
}
if ([numbers characterIsMember:[string characterAtIndex:0]]) {
if ( currentLength == 3 )
{
if (range.length != 1)
{
NSString *firstThreeDigits = [textField.text substringWithRange:NSMakeRange(0, 3)];
NSString *updatedText;
if ([string isEqualToString:#"-"])
{
updatedText = [NSString stringWithFormat:#"%#",firstThreeDigits];
}
else
{
updatedText = [NSString stringWithFormat:#"%#-",firstThreeDigits];
}
[textField setText:updatedText];
}
}
else if ( currentLength > 3 && currentLength < 8 )
{
if ( range.length != 1 )
{
NSString *firstThree = [textField.text substringWithRange:NSMakeRange(0, 3)];
NSString *dash = [textField.text substringWithRange:NSMakeRange(3, 1)];
NSUInteger newLenght = range.location - 4;
NSString *nextDigits = [textField.text substringWithRange:NSMakeRange(4, newLenght)];
NSString *updatedText = [NSString stringWithFormat:#"%#%#%#",firstThree,dash,nextDigits];
[textField setText:updatedText];
}
}
else if ( currentLength == 8 )
{
if ( range.length != 1 )
{
NSString *areaCode = [textField.text substringWithRange:NSMakeRange(0, 3)];
NSString *firstThree = [textField.text substringWithRange:NSMakeRange(4, 3)];
NSString *nextDigit = [textField.text substringWithRange:NSMakeRange(7, 1)];
[textField setText:[NSString stringWithFormat:#"(%#) %#-%#",areaCode,firstThree,nextDigit]];
}
}
}
else {
return NO;
}
return YES;
}
I have a two string like "SANFRANSICO" and "CHICAGO"
Now i want to make it like the string is in reverse but in a single string like "OOCGIASCNIAHRCFNAS"
I have done code but it gives me wrong result
check out my code
- (NSString *)changeString1:(NSString *)string string2:(NSString *)string2{
int first = [string length];
int second = [string2 length];
int total = first+second;
NSMutableString *str = [[NSMutableString alloc] init];
string = [self reverseString:string];
string2 = [self reverseString:string2];
for (int i=0; i<total+1; i++)
{
if (i%2==1) {
int j = i/2;
if(j < second){
NSString *ichar = [NSString stringWithFormat:#"%c", [string2 characterAtIndex:j]];
[str appendString:ichar];
}
else{
NSString *ichar = [NSString stringWithFormat:#"%c", [string characterAtIndex:j+1]];
NSLog(#"222 %d %#",j+1, ichar );
[str appendString:ichar];
check = YES;
}
}
else {
int j = i/2;
if(check == YES){
}
else{
NSString *ichar = [NSString stringWithFormat:#"%c", [string characterAtIndex:j]];
NSLog(#"1111 %d %#",j, ichar );
[str appendString:ichar];
}
}
}
return str;
}
I found the answer very soon after post this question sorry for posting this question
check out my answer
- (NSString *)changeString1:(NSString *)string string2:(NSMutableString *)string2{
int first = [string length];
int second = [string2 length];
string = [self reverseString:string];
string2 = [self reverseString:string2];
for(int i =second; i<first; i ++){
[string2 appendString:#" "];
}
int total = first*2;
NSMutableString *str = [[NSMutableString alloc] init];
for (int i=0; i<total; i++)
{
if (i%2==1) {
int j = i/2;
if(j < second){
NSString *ichar = [NSString stringWithFormat:#"%c", [string2 characterAtIndex:j]];
[str appendString:ichar];
}
}
else {
int j = i/2;
if(j < first){
NSString *ichar = [NSString stringWithFormat:#"%c", [string characterAtIndex:j]];
[str appendString:ichar];
}
else{
NSString *ichar = [NSString stringWithFormat:#"%c", [string2 characterAtIndex:j]];
[str appendString:ichar];
}
}
}
NSLog(#"str %#", str);
return str;
}
How can I check if the UIKeyboardTypeDecimalPad has a dot/comma? I need this to check how many dots/commas are entered so I can limit them to only 1. I know how to do this when I know that the UIKeyboardTypeDecimalPad has the comma.
-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
NSCharacterSet *cs;
NSString *filtered;
NSString *newString = [textField.text stringByReplacingCharactersInRange:range withString:string];
if ([textField.text rangeOfString:#","].location == NSNotFound) {
cs = [[NSCharacterSet characterSetWithCharactersInString:NUMBERSPERIOD] invertedSet];
filtered = [[string componentsSeparatedByCharactersInSet:cs] componentsJoinedByString:#""];
return [string isEqualToString:filtered];
}
else {
cs = [[NSCharacterSet characterSetWithCharactersInString:NUMBERS] invertedSet];
filtered = [[string componentsSeparatedByCharactersInSet:cs] componentsJoinedByString:#""];
NSUInteger count = 0, length = [newString length];
NSRange range = NSMakeRange(0, length);
while(range.location != NSNotFound)
{
range = [newString rangeOfString: #"," options:0 range:range];
if(range.location != NSNotFound)
{
range = NSMakeRange(range.location + range.length, length - (range.location + range.length));
count++;
}
}
if (count < 2) {
NSArray *sep = [newString componentsSeparatedByString:#","];
if([sep count]>=2)
{
NSString *sepStr=[NSString stringWithFormat:#"%#",[sep objectAtIndex:1]];
return !([sepStr length]>2);
}
return YES;
}
return NO;
}
}
Is there easy way to check if the keyboard has the "," or "."?
I suspect the character on that key is governed by the current locale. I say I suspect because I have not tested this. If this is correct the following should allow you to determine whether a comma or period/decimal point is there:
NSString *symbol = [[NSLocale currentLocale] objectForKey:NSLocaleDecimalSeparator];