Reputation: 4441
I have UITextField whose owner is the delegate for the textfield. I have declared the UITextField as below:
self.thresholdValueTextField.delegate = self;
NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init];
[numberFormatter setNumberStyle:NSNumberFormatterCurrencyStyle];
[numberFormatter setMaximumFractionDigits:2];
[numberFormatter setMinimumFractionDigits:2];
self.thresholdValueTextField.text = [numberFormatter stringFromNumber:[NSNumber numberWithInt:0]];
When the user keeps pressing on the back button even the string is $0.00, my app crashes due to the following error:
*** Terminating app due to uncaught exception 'NSDecimalNumberOverflowException', reason: 'NSDecimalNumber overflow exception'
Given below is the code that handles textField: shouldChangeCharactersInRange: delegate method:
- (BOOL)textField:(UITextField*)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString*)string
{
NSInteger MAX_DIGITS = 10; // $999,999,999.99
NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init];
[numberFormatter setNumberStyle:NSNumberFormatterCurrencyStyle];
[numberFormatter setMaximumFractionDigits:2];
[numberFormatter setMinimumFractionDigits:2];
NSString *stringMaybeChanged = [NSString stringWithString:string];
if (stringMaybeChanged.length > 1)
{
NSMutableString *stringPasted = [NSMutableString stringWithString:stringMaybeChanged];
[stringPasted replaceOccurrencesOfString:numberFormatter.currencySymbol
withString:@""
options:NSLiteralSearch
range:NSMakeRange(0, [stringPasted length])];
[stringPasted replaceOccurrencesOfString:numberFormatter.groupingSeparator
withString:@""
options:NSLiteralSearch
range:NSMakeRange(0, [stringPasted length])];
NSDecimalNumber *numberPasted = [NSDecimalNumber decimalNumberWithString:stringPasted];
stringMaybeChanged = [numberFormatter stringFromNumber:numberPasted];
}
UITextRange *selectedRange = [textField selectedTextRange];
UITextPosition *start = textField.beginningOfDocument;
NSInteger cursorOffset = [textField offsetFromPosition:start toPosition:selectedRange.start];
NSMutableString *textFieldTextStr = [NSMutableString stringWithString:textField.text];
NSUInteger textFieldTextStrLength = textFieldTextStr.length;
[textFieldTextStr replaceCharactersInRange:range withString:stringMaybeChanged];
[textFieldTextStr replaceOccurrencesOfString:numberFormatter.currencySymbol
withString:@""
options:NSLiteralSearch
range:NSMakeRange(0, [textFieldTextStr length])];
[textFieldTextStr replaceOccurrencesOfString:numberFormatter.groupingSeparator
withString:@""
options:NSLiteralSearch
range:NSMakeRange(0, [textFieldTextStr length])];
[textFieldTextStr replaceOccurrencesOfString:numberFormatter.decimalSeparator
withString:@""
options:NSLiteralSearch
range:NSMakeRange(0, [textFieldTextStr length])];
if (textFieldTextStr.length <= MAX_DIGITS)
{
NSDecimalNumber *textFieldTextNum = [NSDecimalNumber decimalNumberWithString:textFieldTextStr];
NSDecimalNumber *divideByNum = [[[NSDecimalNumber alloc] initWithInt:10] decimalNumberByRaisingToPower:numberFormatter.maximumFractionDigits];
NSDecimalNumber *textFieldTextNewNum = [textFieldTextNum decimalNumberByDividingBy:divideByNum];
NSString *textFieldTextNewStr = [numberFormatter stringFromNumber:textFieldTextNewNum];
textField.text = textFieldTextNewStr;
if (cursorOffset != textFieldTextStrLength)
{
NSInteger lengthDelta = textFieldTextNewStr.length - textFieldTextStrLength;
NSInteger newCursorOffset = MAX(0, MIN(textFieldTextNewStr.length, cursorOffset + lengthDelta));
UITextPosition* newPosition = [textField positionFromPosition:textField.beginningOfDocument offset:newCursorOffset];
UITextRange* newRange = [textField textRangeFromPosition:newPosition toPosition:newPosition];
[textField setSelectedTextRange:newRange];
}
}
return NO;
}
May I know what's causing this error?
Upvotes: 1
Views: 4151
Reputation: 4441
The issue was with the DecimalNumberByDividingBy for [NSDecimalNumber Zero] and NaN occurence.
Updating the code for DecimalNumberByDivindingBy solved it
NSDecimalNumber *textFieldTextNewNum;
if ([textFieldTextNum compare:[NSDecimalNumber zero]] == NSOrderedSame || [[NSDecimalNumber notANumber] isEqualToNumber:textFieldTextNum]) {
textFieldTextNewNum = [NSDecimalNumber zero];
}else{
textFieldTextNewNum = [textFieldTextNum decimalNumberByDividingBy:divideByNum];
}
Upvotes: 4