美文网首页iOS开发常用iOS DeveloperiOS学习专题
一句代码实现银行卡手机号输入时格式化

一句代码实现银行卡手机号输入时格式化

作者: 李瘦瘦不胖 | 来源:发表于2017-12-07 18:14 被阅读267次

    源码地址:https://github.com/csfuwwc/NSNumberFormatterTest

    2018.01.18更新

    NSString+More 新增<已有数据展示时格式化>
    
    //转换为手机号格式  xxx xxxx xxxx
    - (NSString *)phoneFormatter;
    
    //转换为银行卡格式 xxxx xxxx xxxx xxxx xxx
    - (NSString *)banCardFormatter;
    

    位数不够时也显示上述格式,
    如1391111111 显示为 139 1111 111
    如622848040256489001显示为6228 4804 0256 4890 01

    UITextField+More 新增<输入数据时格式化显示>
    
    //格式-手机号/银行卡/金额等等
    @property (assign, nonatomic)UIInputTextFieldStyle style;
    
    //最大输入位数
    @property (assign, nonatomic)NSInteger maxInputLength;
    
    //最终字符
    @property (assign, nonatomic)NSString * resultString;
    

    style:控制格式,目前支持手机号/银行卡 后期将扩展支持小数位数自定义(如小数点后指定位数,有其他需求的童鞋可以留言~~~)

    maxInputLength:控制位数,当超过指定位数时不可再输入

    resultString:最终字符,主要针对手机号/银行卡格式输入控制时获取实际字符

    原文

    场景一、手机号/银行卡 格式化<展示>

    核心代码

    - (NSString *)PhoneFormatter:(NSString*)str
    {
         NSNumber * number = [NSNumber numberWithInteger:[str integerValue]];
     
         NSNumberFormatter * formatter = [NSNumberFormatter new];
    
         //设置分隔符
         [formatter setGroupingSeparator:@" "];
    
         //设置分割格式
         formatter.positiveFormat = @"###,###0";
    
         NSString * string = [formatter stringFromNumber:number];
    
         NSLog(@"%@",string);
    }
    

    输入手机号 13911112222 输出结果如下:

    139 1111 2222
    

    同理,输入一个银行卡号 6228480402564890018 输出结果如下:

    622 8480 4025 6489 0018
    

    适用场景:已有数据,格式化展示。

    场景二、手机号/银行卡 格式化<输入时>

    如果继续使用上面方法,输入过程中数字跳动,逼死强迫症。有兴趣的同学可以试试。

    核心代码

    NSNumber * number = [NSNumber numberWithInteger:[string integerValue]];
    NSNumberFormatter * formatter = [NSNumberFormatter new];
        
    //设置分隔符
    [formatter setGroupingSeparator:@" "];
    //设置使用组分割
    formatter.usesGroupingSeparator = YES;
        
    // 数字分割的尺寸<从右向左> 
    formatter.groupingSize = ([string length]-3)%4>0?([string length]-3)%4:4;
        
    //除了groupingSize决定的尺寸外,其他数字位分割的尺寸
    formatter.secondaryGroupingSize = [string length]>7?4:3;
                
    //获取格式化后的字符
    tf.text  = [formatter stringFromNumber:number];
    
    formatter.gif

    适用场景:输入字符同时要求格式。

    封装集成

    在项目中,通过封装TextField+More分类,使用时,只需要一句代码即可实现:

    self.inputTextField.style = UIInputTextFieldStyle_Phone;
    

    下面看下TextField+More的实现

    <UITextField+More.h>
    
    //  UITextField+More.h
    //  NSNumberFormatterTest
    //
    //  Created by 李彦鹏 on 2017/12/7.
    //  Copyright © 2017年 csfuwwc. All rights reserved.
    //
    
    #import <UIKit/UIKit.h>
    
    typedef void(^EditBlock)(UITextField * tf);
    
    typedef enum : NSUInteger {
    
         UIInputTextFieldStyle_Phone = 1, //手机号
    
         UIInputTextFieldStyle_BankCard = 2, //银行卡
    
    } UIInputTextFieldStyle;
    
    @interface UITextField (More)<UITextFieldDelegate>
    
    
    //扩展输入框style属性,使用时直接赋值style即可实现格式化功能
    @property (assign, nonatomic)UIInputTextFieldStyle style;
    
    
    /**
     *  输入框事件触发回调
     *
     *  @param event 事件
     *  @param block 回调
     */
     
    - (void)handleControlEvent:(UIControlEvents)event withBlock:(EditBlock)block;
    
    
     
    <UITextField+More.m>
    
    //
    //  UITextField+More.m
    //  NSNumberFormatterTest
    //
    //  Created by 李彦鹏 on 2017/12/7.
    //  Copyright © 2017年 csfuwwc. All rights reserved.
    //
      
    #import "UITextField+More.h"
    #import <objc/runtime.h>
    
    @implementation UITextField (More)
    
    
     #pragma mark - UIControlEventBlock  输入字符Block回调实现
    
    static const char * TextFieldMoreKey = "TextFieldMoreKey";
    
    -(void)handleControlEvent:(UIControlEvents)event withBlock:(EditBlock)block
    {
        objc_setAssociatedObject(self, TextFieldMoreKey, block, OBJC_ASSOCIATION_COPY_NONATOMIC);
        [self addTarget:self action:@selector(editEvent:) forControlEvents:event];
    }
    
    -(void)editEvent:(UITextField *)textField
    {
        EditBlock block = objc_getAssociatedObject(self, TextFieldMoreKey);
    
        if (block)
        {
            block(textField);
        }
    }
    
    
    
    #pragma mark - UITextFieldInputSytle 输入字符格式化核心部分
    
    static const char * TextFieldStyleKey = "TextFieldStyleKey";
    
    - (void)setStyle:(UIInputTextFieldStyle)style
    {
         objc_setAssociatedObject(self, TextFieldStyleKey, @(style), OBJC_ASSOCIATION_ASSIGN);
    
         self.delegate  = self;
    
         //检测输入-格式化
         [self formatterInputString];
    }
    
    - (UIInputTextFieldStyle)style
    {
         return [objc_getAssociatedObject(self, TextFieldStyleKey) integerValue];
    }
    
    
    //格式化输入字符
    - (void)formatterInputString
    {
        [self handleControlEvent:UIControlEventEditingChanged withBlock:^(UITextField *tf) {
       
        //去空
        NSString * string = [tf.text stringByReplacingOccurrencesOfString:@" " withString:@""];
        
        if ([string length]==0)
        {
            return;
        }
        
        NSNumber * number = [NSNumber numberWithInteger:[string integerValue]];
        NSNumberFormatter * formatter = [NSNumberFormatter new];
        
        //设置分隔符
        [formatter setGroupingSeparator:@" "];
        //设置使用组分割
        formatter.usesGroupingSeparator = YES;
        
        // 数字分割的尺寸<从右向左> 
        formatter.groupingSize = ([string length]-3)%4>0?([string length]-3)%4:4;
        
        //除了groupingSize决定的尺寸外,其他数字位分割的尺寸
        formatter.secondaryGroupingSize = [string length]>7?4:3;
                
        //获取格式化后的字符
        tf.text  = [formatter stringFromNumber:number];
        
        
        }];
    }
    
    
    
    
    #pragma mark - UITextFieldDelegate
    
    -(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
    {
        if (self.style != 0 && ![string isEqualToString:@""])
        {
        
            NSString * string = [textField.text stringByReplacingOccurrencesOfString:@" " withString:@""];
    
        
            switch (self.style)
            {
                case UIInputTextFieldStyle_Phone:
                {
                    //如果超过11位则不允许再输入
                    if ([string length]>= 11)
                    {
                        return NO;
                    }
                 }
                    break;
                case UIInputTextFieldStyle_BankCard:
                {
                    //如果超过16位则不允许再输入
                    if ([string length]>= 16)
                    {
                        return NO;
                    }
                }
                   break;
                default:
                   break;
            }
        }
    
        return YES;
    }
    
    
    @end
    

    源码地址:https://github.com/csfuwwc/NSNumberFormatterTest

    结束语

    更多格式
    http://unicode.org/reports/tr35/tr35-6.html#Number_Format_Patterns

    PS:NSNumberFormatter远比想象的强大哟!

    谢谢大家。

    相关文章

      网友评论

      • 0d183d5f7398:好像不能判断是否电话号码和是否银行卡号
      • deepindo:你好,请问下,这个显示格式对了,如何输出tf里面的内容呢
        李瘦瘦不胖:新增了resultString字段获取实际内容~可以下载源码查看
        李瘦瘦不胖:@deepindo NSString * string = [textField.text stringByReplacingOccurrencesOfString:@" " withString:@""];

      本文标题:一句代码实现银行卡手机号输入时格式化

      本文链接:https://www.haomeiwen.com/subject/aqjjixtx.html