UITextField 对输入金额的约束
[2016/1/18更新] -- 五个人辛辛苦苦干了一年的项目终于上线了,今天有空看了一下正则表达式教程,然后开始rebuild之前的种种对字符串的约束,首先就从这个金额输入框开始吧,修改后的代码如下:
1 - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{ 2 NSString * pureString = textField.text; 3 NSString * laterString = [NSString stringWithFormat:@"%@%@",pureString,string]; 4 5 if ([pureString isEqualToString:@""] && [@"0." containsString:string]) { 6 textField.text = @"0."; 7 return NO; 8 }else{ 9 if ([pureString containsString:@"."]) { 10 NSString *regex = @"[0-9]{0,3}.[0-9]{0,2}"; //所限制的数字在0.00到999.99之间 11 NSPredicate *test = [NSPredicate predicateWithFormat:@"SELF MATCHES %@",regex]; 12 if ([test evaluateWithObject:laterString]) { 13 return YES; 14 } 15 return NO; 16 }else{ 17 if ([string isEqualToString:@"."]) { 18 return YES; 19 } 20 21 NSString *regex = @"[0-9]{0,3}"; 22 NSPredicate *test = [NSPredicate predicateWithFormat:@"SELF MATCHES %@",regex]; 23 if ([test evaluateWithObject:laterString]) { 24 return YES; 25 } 26 return NO; 27 } 28 } 29 return NO; 30 }
这是第一次写正则表达式,节省了半数的代码量,用时大概五分钟(主要是有了上次的经验之后思路更加清晰了),感觉这次使用正则表达式的最大好处就是约束方便,原来用好多行if-else才能做出的判断,现在五行代码即可实现,是不是很方便?
这儿有个网站可供像我这样的正则菜鸟学习正则表达式,好东西就要和大家一起分享,仅此。
[2016/1/13更新] -- 对于输入限制这些东西,最好的方法还是使用正则表达式,不仅代码简洁优雅,而且可以免去很多意想不到的结果。最近刚开始重视正则表达式的用法,还不太懂,日后更新。
[2015/7/27] -- 输入金额的文本框是一个逻辑比较复杂的问题,要考虑的条件也比较的多。我考虑的主要有以下几点:
1、输入数字保留至小数点后两位
2、只能输入一个小数点(因为之前看到别人博客的代码遗漏了这一点)
3、如果用户第一个输入的是小数点,则自动为其填充 ‘.’ 前的 ‘0’
下面是代码,引用时需要设置一个纪录小数点个数的全局变量,如下:
@property (nonatomic,assign)NSInteger numberOfPoint; //小数点个数
主体代码如下:
1 /** 2 * 限制输入两位小数 3 * 输入小数点后两位之后,再输入其他字符回收键盘 4 */ 5 - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{ 6 NSMutableString * currentString = [NSMutableString stringWithString:textField.text]; 7 NSMutableString * futureString = [NSMutableString stringWithFormat:@"%@%@",currentString,string]; 8 9 //禁止输入除数字和‘.’之外的其他字符 10 if (![@"1234567890." containsString:string] && ![string isEqualToString:@""]) { 11 return NO; 12 } 13 14 NSInteger flag=0; 15 const NSInteger limited = 2; 16 if (![textField.text containsString:@"."]){ 17 _numberOfPoint = 0; 18 }else if(0 == _numberOfPoint){ 19 _numberOfPoint = 1; 20 } 21 22 //1、如果text field中没有字符,且输入的字符位 ‘.’,则自动填充 ‘0’ 23 if (textField.text.length < 1 && [string isEqualToString:@"."]) { 24 textField.text = @"0"; 25 _numberOfPoint ++; 26 return YES; 27 }else if(0 == textField.text.length && [string isEqualToString:@"0"]) { 28 textField.text = @"0."; 29 _numberOfPoint ++; 30 return NO; 31 }else { 32 //只能有一个小数点 33 if (_numberOfPoint > 0 && [string isEqualToString:@"."]) { 34 return NO; 35 } 36 if (_numberOfPoint == 0 && [string isEqualToString:@"."]) { 37 _numberOfPoint ++; 38 } 39 40 if (range.location >= futureString.length - 3) { 41 //从后往前遍历字符串flag用于记录小数点后的数字位数 42 for (int i = (int)futureString.length-1 ; i>=0; i--) { 43 if ([futureString characterAtIndex:i] == '.') { 44 if (flag > limited) { 45 //回收键盘 46 [textField resignFirstResponder]; 47 return NO; 48 } 49 break; 50 } 51 flag++; 52 } 53 } 54 } 55 return YES; 56 }
上面这些考虑完之后,还可以有下面这些考虑:
1、禁用输入框的选择、复制、粘贴等功能
要实现上面的这个考虑需要写一个继承于UITextField的类,重写canPerformAction: withSender:方法就可以了,尤其他需要的话可以根据规律进行设置。
主体代码如下:
- (BOOL)canPerformAction:(SEL)action withSender:(id)sender{ if (action == @selector(paste:) || //粘贴 action == @selector(select:) || //选择 action == @selector(selectAll:)) //全选 { return NO; } return [super canPerformAction:action withSender:sender]; }
如果有些地方不合理,欢迎提出意见!