How can I limit the number of decimal points in a UITextField?
Implement the shouldChangeCharactersInRange method like this:
// Only allow one decimal point// Example assumes ARC - Implement proper memory management if not using.- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string { NSString *newString = [textField.text stringByReplacingCharactersInRange:range withString:string]; NSArray *arrayOfString = [newString componentsSeparatedByString:@"."]; if ([arrayOfString count] > 2 ) return NO; return YES;}
This creates an array of strings split by the decimal point, so if there is more than one decimal point we will have at least 3 elements in the array.
Here is an example with a regular expression, the example limits to only one decimal point and 2 decimals. You can tweak it to fit your needs.
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string { NSString *newString = [textField.text stringByReplacingCharactersInRange:range withString:string]; NSString *expression = @"^[0-9]*((\\.|,)[0-9]{0,2})?$"; NSError *error = nil; NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:expression options:NSRegularExpressionCaseInsensitive error:&error]; NSUInteger numberOfMatches = [regex numberOfMatchesInString:newString options:0 range:NSMakeRange(0, [newString length])]; return numberOfMatches != 0;}
Swift 3 Implement this UITextFieldDelegate method to prevent user from typing an invalid number:
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { let text = (textField.text ?? "") as NSString let newText = text.replacingCharacters(in: range, with: string) if let regex = try? NSRegularExpression(pattern: "^[0-9]*((\\.|,)[0-9]*)?$", options: .caseInsensitive) { return regex.numberOfMatches(in: newText, options: .reportProgress, range: NSRange(location: 0, length: (newText as NSString).length)) > 0 } return false}
It is working with both comma or dot as decimal separator. You can also limit number of fraction digits using this pattern: "^[0-9]*((\\.|,)[0-9]{0,2})?$"
(in this case 2).