iOS开发:编辑框格式化输入、删除、插入
2016-06-12 10:14
239 查看
在有些iOS app中需要用到textfield格式化输入、删除、插入,比如银行卡号6215 8888 8888 8888 888等要求4位一分格(手机号同理),如何在编辑框输入和删除时自动显示这样的效果呢,本文有个实现思路。
![](https://img-blog.csdn.net/20160612094507437?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
每次字符编辑后用一个特定的函数对字符串格式化再显示和提交
考虑了从中间插入和删除的情况,以及复制粘贴编辑的情况
限制输入其他字符以及字符个数
添加银行卡号校验规则
实现编辑框委托函数
每次字符输入、删除插入过程中,频繁的使用格式化字符串函数,注意如果是在中间插入和删除字符,则需要对光标进行重新定位,另外,这个函数的return值有时候要返回NO,因为这里手动处理了显示的字符串,所以有时候编辑框的编辑动作不要提交给系统,以免重复处理。
格式化字符串
银行卡校验
Luhn算法:https://en.wikipedia.org/wiki/Luhn_algorithm
github:BankCardNumberFormat
更新:限制金额输入整数位和小数位
预览
思路
重写编辑框的委托函数在里面进行实时监控编辑框内容的变化每次字符编辑后用一个特定的函数对字符串格式化再显示和提交
考虑了从中间插入和删除的情况,以及复制粘贴编辑的情况
限制输入其他字符以及字符个数
添加银行卡号校验规则
实现编辑框委托函数
//do the formatting while textfield text is changing -(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string { //only receive number and backspace input, in case some numberPad receive non-number chars such as sougou T_T NSCharacterSet *characterSet = [NSCharacterSet characterSetWithCharactersInString:@"0123456789\b"]; NSString *checkStr = [self noneSpaseString:string]; if ([checkStr rangeOfCharacterFromSet:[characterSet invertedSet]].location != NSNotFound) return NO; //process the textField text NSString* text = textField.text; //delete if([string length] <= 0) // or [string isEqualToString:''] { NSLog(@"slected range: location %d, length %d", range.location, range.length); //delete the last char if(range.location == text.length - 1) //because already delete one char, so it is text.length - 1 { //actually it will delete twice, first the backspace then delete the space if(text.length >=2 && [text characterAtIndex:text.length-2] == ' ') [textField deleteBackward]; return YES; } //delete in the middle else { NSInteger offset = range.location; NSLog(@"seleted textrange %@", textField.selectedTextRange); if(range.location < text.length && [text characterAtIndex:range.location - 1] == ' ' /*&& [textField.selectedTextRange isEmpty]*/) { [textField deleteBackward]; //Remove the character just before the cursor and redisplay the text. offset--; } [textField deleteBackward]; //format the string textField.text = [self parseString:textField.text]; //reset the cursor pos UITextPosition *newPos = [textField positionFromPosition:textField.beginningOfDocument offset:offset]; textField.selectedTextRange = [textField textRangeFromPosition:newPos toPosition:newPos]; return NO; } } //insert int tail or in the middle else { //limit the number of digits //consider the paste and replace several charcters at one time,ex: 135169 -> 14169, that is:6 + 1 - 2 <19 if([self noneSpaseString:textField.text].length + string.length - range.length > 19) { NSLog(@"text len: %d, string len: %d, range len: %d", [self noneSpaseString:textField.text].length, string.length, range.length); return NO; } [textField insertText:string]; //Add the character text to the cursor and redisplay the text. //format the string textField.text = [self parseString:textField.text]; //move the cursor to the right place NSInteger offset = range.location + string.length; if(range.location == 4 || range.location == 9 || range.location == 14 || range.location == 19) offset++; //reset the cursor pos UITextPosition *newPos = [textField positionFromPosition:textField.beginningOfDocument offset:offset]; textField.selectedTextRange = [textField textRangeFromPosition:newPos toPosition:newPos]; return NO; } return NO; }
每次字符输入、删除插入过程中,频繁的使用格式化字符串函数,注意如果是在中间插入和删除字符,则需要对光标进行重新定位,另外,这个函数的return值有时候要返回NO,因为这里手动处理了显示的字符串,所以有时候编辑框的编辑动作不要提交给系统,以免重复处理。
格式化字符串
//remove the space of string -(NSString*)noneSpaseString:(NSString*)string { return [string stringByReplacingOccurrencesOfString:@" " withString:@""]; } //everytime check the textfield string to format - (NSString*)parseString:(NSString*)textStr { if (!textStr) { return nil; } NSMutableString *formatTextStr = [NSMutableString stringWithString:[textStr stringByReplacingOccurrencesOfString:@" " withString:@""]]; //insert space in step by step,ex: 123456789015 -> 1234 56789015 -> 1234 5678 9015 if(formatTextStr.length > 4) [formatTextStr insertString:@" " atIndex:4]; if(formatTextStr.length > 9) [formatTextStr insertString:@" " atIndex:9]; if(formatTextStr.length > 14) [formatTextStr insertString:@" " atIndex:14]; if(formatTextStr.length > 19) [formatTextStr insertString:@" " atIndex:19]; return formatTextStr; }
银行卡校验
Luhn算法:https://en.wikipedia.org/wiki/Luhn_algorithm
//check whether the bankcard is valid using the Luhn algorithm - (BOOL)isValidBankCard:(NSString *)bankCardNumber { //reverse odd and even sum int oddSum = 0; int evenSum = 0; int Sum = 0; int len = bankCardNumber.length; for(int i = 0; i< len;i++) { NSString *digitStr = [bankCardNumber substringWithRange:NSMakeRange(len - 1 - i, 1)]; int digitVal = digitStr.intValue; if(i & 0x01) { digitVal *= 2; if(digitVal>=10) digitVal -= 9; oddSum += digitVal; } else evenSum += digitVal; } Sum = oddSum + evenSum; if(Sum % 10 == 0) return YES; else return NO; }
源代码下载
csdn:银行卡格式化输入github:BankCardNumberFormat
更新:限制金额输入整数位和小数位
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string { // 正则法限制小数点位数 // NSString *amountText = textField.text; // NSString *regStr = @"^([1-9][\\d]{0,100}|0)(\\.[\\d]{0,1})?$"; // NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regStr]; // BOOL match = [predicate evaluateWithObject:amountText]; // if ([string isEqualToString:@""]) return YES; // 始终允许用户删除 // NSString *tmpStr = [amountText stringByAppendingString:string]; // NSString *numStr = [[tmpStr componentsSeparatedByString:@"."] firstObject]; // NSInteger amount = [numStr integerValue]; // if (([amountText intValue] == 99999999) && (![string isEqualToString:@""])) return NO; // BOOL result = [amountText isEqualToString:@""] ? YES : (match && ((amount <= 99999999) || [string isEqualToString:@"."])); // return result; // 普通法限制小数点位数 int maxIntLen = 8; // 最大整数位 int maxFloatLen = 2; // 最大小数位 // 获取原始的字符串 NSMutableString *numberText = [NSMutableString stringWithString:textField.text]; if (![string isEqualToString:@""]) { // 开头不能直接输入小数点 if (numberText.length == 0 && [string isEqualToString:@"."]) { return NO; } // 以0开头不能多于一位 if ([numberText isEqualToString:@"0"] && ![string isEqualToString:@"."]) { return NO; } // 预先插入字符串 [numberText insertString:string atIndex:range.location]; // 处理字符串,看是否符合要求 // 按小数点分割 NSArray *numsArray = [numberText componentsSeparatedByString:@"."]; if (numsArray.count > 2) { // 如果小数点多余1个,不符合要求 return NO; } else if (numsArray.count == 2) { NSString *intPart = numsArray.firstObject; NSString *floatPart = numsArray.lastObject; if (intPart.length > maxIntLen || floatPart.length > maxFloatLen) { return NO; } } } // 正常删除 return YES; }
相关文章推荐
- IOS之NSArray 中调用的方法详解
- iOS - 富文本AttributedString
- iOS平台下cookie的使用
- iOS ipv6 兼容
- iOS 笔记
- iOS小莲花Versions的SVN工具不能提交.a文件的解决方法
- iOS开发 引入支付宝需要注意的地方
- iOS9新特性(二)
- IPv6介绍及程序支持IPv6的障碍
- 关于 iOS socket 都在这里了
- iOS教你轻松打造瀑布流Layout
- iOS 独立开发记录(下)
- iOS 独立开发记录(上)
- 【代码笔记】iOS-通过颜色来生成一个纯色图片
- 【代码笔记】iOS-通过颜色来生成一个纯色图片
- AVCaptureDevice 曝光模式
- IOS后台机制分析
- iOS 下的相册与图片处理
- IOS加密方式
- iOS 页面之间传参的总结