我是靠谱客的博主 忧郁戒指,最近开发中收集的这篇文章主要介绍iOS开发:编辑框格式化输入、删除、插入预览思路源代码下载,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

在有些iOS app中需要用到textfield格式化输入、删除、插入,比如银行卡号6215 8888 8888 8888 888等要求4位一分格(手机号同理),如何在编辑框输入和删除时自动显示这样的效果呢,本文有个实现思路。


预览




思路

  • 重写编辑框的委托函数在里面进行实时监控编辑框内容的变化
  • 每次字符编辑后用一个特定的函数对字符串格式化再显示和提交
  • 考虑了从中间插入和删除的情况,以及复制粘贴编辑的情况
  • 限制输入其他字符以及字符个数
  • 添加银行卡号校验规则

实现编辑框委托函数
//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:@"0123456789b"];
    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开发:编辑框格式化输入、删除、插入预览思路源代码下载的全部内容,希望文章能够帮你解决iOS开发:编辑框格式化输入、删除、插入预览思路源代码下载所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(53)

评论列表共有 0 条评论

立即
投稿
返回
顶部