iOS开发 长串数字每隔3位添加空格显示

2019-10-24  本文已影响0人  明月名

需求:

app是做视频会议的,有个输入会议号的环节,最长为15位。在显示的地方,需要每隔3位添加一个空格

问题:

只做展示,做法很简单,但是做成可以在中间删除,会引发一系列的问题,主要都是光标位置的问题

解决方案:

//1、判断是否为数字(写在NSSting的分类里)

//判断非法字符
+ (BOOL)check_isAllow:(NSString *)content {
    // 特殊字符
    NSString *str =@"^[A-Za-z0-9_\\s\\u4e00-\u9fa5]+$";
    NSPredicate *emailTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", str];
    if (![emailTest evaluateWithObject:content]) {
        return NO;
    }
    //空格检测不出来,需单独判断
    NSRange range = [content rangeOfString:@" "];
    if (range.location != NSNotFound) {
        return NO;
    }
    return YES;
}

//2、设置UITextField代理

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
    //获取当前textfield的光标位置,为后续移动做准备
    NSUInteger currentIndex = [textField offsetFromPosition:textField.beginningOfDocument toPosition:textField.selectedTextRange.start];
    if (textField.tag == 1000) {//该textfield是放在UITableViewCell里面的,因此会有多个输入框,用tag做区分
        if (string.length == 0) {//删除动作,string的长度为0
            if (range.location > 0) {//防止NSRange越界
                range = NSMakeRange(range.location-1, 1);
                NSString *lastString = [textField.text substringWithRange:range];
                currentIndex--;
                if ([lastString isEqualToString:@" "]) {//检测到前面一个字符为0,多进一格
                    currentIndex--;
                }
            }
        }else if (!string.check_isAllow) {//判断是否为数字
            return NO;
        }else {//正 常移动光标
            currentIndex ++;
            if (currentIndex%4 == 0) {
                currentIndex ++;
            }
        }
    }
    _selectIndex = MIN(19, currentIndex);//全局记录光标
    return YES;
}

//3、监听UITextField的文本变化

    [[UITextField new] addTarget:self
                     action:@selector(makeText3Number1Space:)
             forControlEvents:UIControlEventEditingChanged];
-(NSString *)makeText3Number1Space:(UITextField *)tf{
    NSString *text = tf.text;
    NSString *currentStr = [text stringByReplacingOccurrencesOfString:@" " withString:@""];
    if (currentStr.length > 15) {
        text = [currentStr substringToIndex:15];
        tf.text = text;
        [self textFieldDidChange:tf];
        return text;
    }//这里大于15位的时候,直接不进行任何操作
    
    // 每隔3位,j插入一个空格
    NSMutableString *muStr = [currentStr mutableCopy];
    if (muStr.length > 3) {
        int i=2;
        while (i<muStr.length) {
            if ((i+1)%4==0) {
                [muStr insertString:@" " atIndex:i];
            }
            i++;
        }
        if (muStr.length == 4) {
            [muStr deleteCharactersInRange:NSMakeRange(3, 1)];
        }
        text = [muStr copy];
    }
    if (text.length == 4) {//从@“123 4”删除成@“123 ”的时候,空格会被保留,光标后面会多个空格
        text = [text stringByReplacingOccurrencesOfString:@" " withString:@""];
    }
    tf.text = text;
    
    //根据全局的光标index位置,重新设置光标选中的位置
    UITextPosition *targetPosition = [tf positionFromPosition:[tf beginningOfDocument] offset:_selectIndex];
    [tf setSelectedTextRange:[tf textRangeFromPosition:targetPosition toPosition :targetPosition]];
    return text;//返回字符串,存在model里面
}

整个流程大体就是:
1、判断输入字符——》获取光标位置——》计算
2、删空格获取string——》计算并加空格——》移动光标

未完善:

1、光标移动到号码中间时,删除空格,此时空格不会被删除,有待后续完善

2、从粘贴板copy到UITextfield的话,光标位置会错乱,不想因为监听复制事件而造成内存泄漏,暂时还没做

上一篇下一篇

猜你喜欢

热点阅读