? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?支付寶、微信添加銀行卡號輸入框格式限制之任意位置回刪比較
最近工作中遇到一個問題,就是一個輸入銀行卡號的輸入框,如下圖,微信的處理是光標放在空格后面不能刪除,并且點擊刪除后自動回退到文本最后,還有就是每刪除一個數(shù)字光標也自動回退到最后;而支付寶的處理則是,光標無論放在任何位置都能刪除,并且不回退到最后。我們暫不去評判誰的用戶體驗好,作為開發(fā)人員,先看看兩種怎么實現(xiàn)吧。上代碼吧。

微信的做法:
-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{
if(textField?==?self.text_cardno)?{
NSString?*text?=?[self.text_cardno?text];
NSCharacterSet?*characterSet?=?[NSCharacterSet?characterSetWithCharactersInString:@"0123456789\b"];
string?=?[string?stringByReplacingOccurrencesOfString:@"?"withString:@""];
if([string?rangeOfCharacterFromSet:[characterSet?invertedSet]].location?!=?NSNotFound)?{
returnNO;
}
text?=?[text?stringByReplacingCharactersInRange:range?withString:string];
text?=?[text?stringByReplacingOccurrencesOfString:@"?"withString:@""];
NSString?*newString?=?@"";
while(text.length?>?0)?{
NSString?*subString?=?[text?substringToIndex:MIN(text.length,?4)];
newString?=?[newString?stringByAppendingString:subString];
if(subString.length?==?4)?{
newString?=?[newString?stringByAppendingString:@"?"];
}
text?=?[text?substringFromIndex:MIN(text.length,?4)];
}
newString?=?[newString?stringByTrimmingCharactersInSet:[characterSet?invertedSet]];
//?限制長度
if(newString.length?>=?24)?{
returnNO;
}
[self.text_cardno?setText:newString];
returnNO;
}
returnYES;
}
//?銀行卡號轉(zhuǎn)正常號?-?去除4位間的空格
-(NSString?*)bankNumToNormalNum
{
return[self.text_cardno.text?stringByReplacingOccurrencesOfString:@"?"withString:@""];
}
支付寶的做法:
//每組個數(shù)
staticNSIntegerconstkGroupSize =4;
- (BOOL)textField:(UITextField*)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString*)string {
if(textField ==self.beforPhoneNumTextField) {
if(range.location>=11)
returnNO;// return NO to not change text
returnYES;
}elseif(textField ==self.verfiCodeTextField){
if(range.location>=6)
returnNO;// return NO to not change text
returnYES;
}elseif(textField ==self.bankCardNumTextField) {
NSString*text = textField.text;
NSString*beingString = [textField.textstringByReplacingCharactersInRange:rangewithString:string];
NSString*cardNo = [selfremovingSapceString:beingString];
//校驗卡號只能是數(shù)字,且不能超過20位
if( (string.length!=0&& ![selfisValidNumbers:cardNo]) || cardNo.length>20) {
returnNO;
}
//獲取【光標右側(cè)的數(shù)字個數(shù)】
NSIntegerrightNumberCount = [selfremovingSapceString:[textsubstringFromIndex:textField.selectedRange.location+ textField.selectedRange.length]].length;
//輸入長度大于4 需要對數(shù)字進行分組,每4個一組,用空格隔開
if(beingString.length>kGroupSize) {
textField.text= [selfgroupedString:beingString];
}else{
textField.text= beingString;
}
text = textField.text;
/**
* 計算光標位置(相對末尾)
* 光標右側(cè)空格數(shù) = 所有的空格數(shù) - 光標左側(cè)的空格數(shù)
* 光標位置 = 【光標右側(cè)的數(shù)字個數(shù)】+ 光標右側(cè)空格數(shù)
*/
NSIntegerrightOffset = [selfrightOffsetWithCardNoLength:cardNo.lengthrightNumberCount:rightNumberCount];
NSRangecurrentSelectedRange =NSMakeRange(text.length- rightOffset,0);
//如果光標左側(cè)是一個空格,則光標回退一格
if(currentSelectedRange.location>0&& [[textsubstringWithRange:NSMakeRange(currentSelectedRange.location-1,1)]isEqualToString:@" "]) {
currentSelectedRange.location-=1;
}
[textField setSelectedRange:currentSelectedRange];
returnNO;
}
returnYES;
}
/**
*計算光標相對末尾的位置偏移
*
*@param length卡號的長度(不包括空格)
*@param rightNumberCount 光標右側(cè)的數(shù)字個數(shù)
*
*@return 光標相對末尾的位置偏移
*/
- (NSInteger)rightOffsetWithCardNoLength:(NSInteger)length rightNumberCount:(NSInteger)rightNumberCount {
NSIntegertotalGroupCount = [selfgroupCountWithLength:length];
NSIntegerleftGroupCount = [selfgroupCountWithLength:length - rightNumberCount];
NSIntegertotalWhiteSpace = totalGroupCount -1>0? totalGroupCount -1:0;
NSIntegerleftWhiteSpace = leftGroupCount -1>0? leftGroupCount -1:0;
returnrightNumberCount + (totalWhiteSpace - leftWhiteSpace);
}
/**
*校驗給定字符串是否是純數(shù)字
*
*@param numberStr 字符串
*
*@return 字符串是否是純數(shù)字
*/
- (BOOL)isValidNumbers:(NSString*)numberStr {
NSString* numberRegex =@"^[0-9]+$";
NSPredicate*numberPre = [NSPredicatepredicateWithFormat:@"SELF MATCHES %@",numberRegex];
return[numberPreevaluateWithObject:numberStr];
}
/**
*去除字符串中包含的空格
*
*@param str 字符串
*
*@return 去除空格后的字符串
*/
- (NSString*)removingSapceString:(NSString*)str {
return[strstringByReplacingOccurrencesOfString:@" "withString:@""options:NSCaseInsensitiveSearchrange:NSMakeRange(0, str.length)];
}
/**
*根據(jù)長度計算分組的個數(shù)
*
*@param length 長度
*
*@return 分組的個數(shù)
*/
- (NSInteger)groupCountWithLength:(NSInteger)length {
return(NSInteger)ceilf((CGFloat)length /kGroupSize);
}
/**
*給定字符串根據(jù)指定的個數(shù)進行分組,每一組用空格分隔
*
*@param string 字符串
*
*@return 分組后的字符串
*/
- (NSString*)groupedString:(NSString*)string {
NSString*str = [selfremovingSapceString:string];
NSIntegergroupCount = [selfgroupCountWithLength:str.length];
NSMutableArray*components = [[NSMutableArrayalloc]init];
for(NSIntegeri =0; i < groupCount; i++) {
if(i*kGroupSize+kGroupSize> str.length) {
[componentsaddObject:[strsubstringFromIndex:i*kGroupSize]];
}else{
[componentsaddObject:[strsubstringWithRange:NSMakeRange(i*kGroupSize,kGroupSize)]];
}
}
NSString*groupedString = [componentscomponentsJoinedByString:@" "];
returngroupedString;
}