Reputation: 6940
I building payment app and i want that text field will only be able to:
1) Have no more then one dot
2) Have no more then 2 symbols after dot
Because i want to add payment amount to text field there is no reason to have more then one dot or add more then 2 symbols for small currency items (like cents).
Is there any simple way to do that?
Upvotes: 1
Views: 3043
Reputation: 2906
This is objective c example. Currently I am using this for currency validation.
NSString category class
- (BOOL)isValidNumber{
NSString *regxString = @"^([0-9]*)(\\.([0-9]+)?)?$";
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:regxString
options:NSRegularExpressionCaseInsensitive
error:nil];
NSUInteger matchCount = [regex numberOfMatchesInString:self
options:0
range:NSMakeRange(0, [self length])];
if (matchCount == 0){
return NO;
}
return YES;
}
And textfield change event
- (void)textFieldDidChange :(UITextField *)textField {
NSArray *seperatedString = [textField.text componentsSeparatedByString:@"."];
if ([seperatedString count] > 1) {
if ([((NSString *)[seperatedString objectAtIndex:1]) length] > MAX_DECIMAL) {
[self textFieldRemoveLast:textField];
} else if([textField.text isValidLength:NUMBER_MAX_LIMIT]){
} else {
}
}
}
}
- (void)textFieldRemoveLast:(UITextField *)textField {
if (textField.text.length > 0) {
textField.text = [textField.text substringToIndex:[textField.text length] - 1];
}
}
textfield change event, I am checking the number of "." and based on that I am deleting the last character. And you can set the maximum number of decimals.
Swift
func isValidNumber() -> Bool {
let regxString = "^([0-9]*)(\\.([0-9]+)?)?$"
let regex = try? NSRegularExpression(pattern: regxString, options: .caseInsensitive)
let matchCount: Int? = regex?.numberOfMatches(in: self, options: [], range: NSRange(location: 0, length: length()))
if matchCount == 0 {
return false
}
return true
}
. separete
var seperatedString = textField.text.components(separatedBy: ".")
if seperatedString.count > 1 {
if ((seperatedString[1] as? String)?.count ?? 0) > MAX_DECIMAL {
textFieldRemoveLast(textField)
}
else if textField.text.isValidLength(NUMBER_MAX_LIMIT) {
}
else {
}
}
Remove last
func textFieldRemoveLast(_ textField: UITextField) {
if (textField.text?.count ?? 0) > 0 {
textField.text = (textField.text as? NSString)?.substring(to: (textField.text?.count ?? 0) - 1)
}
}
Upvotes: 1
Reputation:
One possible way of doing this:
class ViewController: UIViewController {
// ...
// MARK: Life Cycle
override func viewDidLoad() {
super.viewDidLoad()
textField.delegate = self
// ...
}
}
extension ViewController : UITextFieldDelegate {
// MARK: UITextFieldDelegate
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
guard let text = textField.text else {
return false
}
if (text.components(separatedBy: ".").count > 1 && string == ".") || (text.components(separatedBy: ".").count > 1 && text.components(separatedBy: ".")[1].characters.count >= 2 && string != "") {
return false
}
return string == "" || (string == "." || Float(string) != nil)
}
}
Upvotes: 0
Reputation: 15758
Try this
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
if (textField.text?.contains("."))!
{
if string == "."
{
return false
}
else if textField.text?.components(separatedBy: ".")[1].characters.count == 2 && range.length != 1{
return false
}
}
return true
}
Upvotes: 1
Reputation: 1754
Use UITextFieldDelegate and below code
// MARK:- TEXTFIELD DELEGATE
func textField(_ textField: UITextField,shouldChangeCharactersIn range: NSRange,replacementString string: String) -> Bool
{
let countdots = (txv_Amount.text?.components(separatedBy: ".").count)! - 1
if countdots > 0 && string == "."
{
return false
}
let MAX_BEFORE_DECIMAL_DIGITS = 3
let MAX_AFTER_DECIMAL_DIGITS = 0
let computationString = (textField.text! as NSString).replacingCharacters(in: range, with: string)
// Take number of digits present after the decimal point.
let arrayOfSubStrings = computationString.components(separatedBy: ".")
if arrayOfSubStrings.count == 1 && computationString.characters.count > MAX_BEFORE_DECIMAL_DIGITS {
return false
} else if arrayOfSubStrings.count == 2 {
let stringPostDecimal = arrayOfSubStrings[1]
return stringPostDecimal.characters.count <= MAX_AFTER_DECIMAL_DIGITS
}
return true
}
Upvotes: 1