iOS开发常用iOS DeveloperiOS学习专题

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

2017-12-07  本文已影响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远比想象的强大哟!

谢谢大家。

上一篇下一篇

猜你喜欢

热点阅读