UITextFeild银行卡/身份证/电话号任意分割.

日常开发中可能有个需求, 1.银行卡每4位添加一个空格  2.电话号:3 4 4 比如(138 8888 8888)3.身份证(411111 20171213 1314) 看了网上许多方法都是输入的时候没问题,但是删除的时候光标就不对. 下面给大家分享一个输入和删除都没问题,根据自己需求随意分割.

gif:

 

代码:

继承一个TextField,CustomTextField:

.h文件

//
//  CustomTextField.h
//  CustomTextField
//
//  Created by Doman on 2017/6/12.
//  Copyright © 2017年 Doman. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface CustomTextField : UITextField

//placeHoler  提示用户的文本
//count  每多少个进行分割,即每隔多少个字符添加空格符号
- (instancetype)initWithPlaceHolder:(NSString*)placeHolder withSeparateCount:(NSInteger)count;

//frame  视图的frame
//placeHoler  提示用户的文本
//count  每多少个进行分割,即每隔多少个字符添加空格符号
- (instancetype)initWithFrame:(CGRect)frame withPlaceHolder:(NSString*)placeHolder withSeparateCount:(NSInteger)count;


//frame  视图的frame
//placeHoler  提示用户的文本
//array  每多少个进行分割,即每隔多少个字符添加空格符号,可不等,但是必须要是字符串对象
- (instancetype)initWithFrame:(CGRect)frame withPlaceHolder:(NSString*)placeHolder withSeparateArray:(NSArray*)countArray;


/**
 *  用户实际输入的内容
 **/
@property (nonatomic,copy) NSString *userInputContent;

/**
 *  限制用户实际输入的数量,默认无限制
 **/
@property (nonatomic,assign) NSInteger limitCount;



@end

.m文件

//
//  CustomTextField.m
//  CustomTextField
//
//  Created by Doman on 2017/6/12.
//  Copyright © 2017年 Doman. All rights reserved.
//

#import "CustomTextField.h"

//placeHolder的左侧距离
static const NSInteger placeHolderLeft = 10;


@interface CustomTextField ()<UITextFieldDelegate>

/**
 *  每隔多少字符分割
 **/
@property (nonatomic,assign) NSInteger separateCount;

/**
 *  提示文本
 **/
@property (nonatomic,copy) NSString *placeHolderString;

/**
 *  placeHolder
 **/
@property (nonatomic,strong) UILabel *placeHolderLabel;

/**
 *  尺寸
 **/
@property (nonatomic,assign) CGRect viewFrame;

/**
 *  分割的array
 **/
@property (nonatomic,strong) NSMutableArray *separateArray;

/**
 *  Location
 **/
@property (nonatomic,assign) NSInteger locationIndex;



@end


@implementation CustomTextField

#pragma mark - 初始化



- (instancetype)initWithPlaceHolder:(NSString*)placeHolder withSeparateCount:(NSInteger)count
{
    return [self initWithFrame:CGRectZero withPlaceHolder:placeHolder withSeparateCount:count];
}

- (instancetype)initWithFrame:(CGRect)frame withPlaceHolder:(NSString*)placeHolder withSeparateCount:(NSInteger)count
{
    self = [super initWithFrame:frame];
    
    if (self) {
        
        self.separateCount = count;
        self.viewFrame = frame;
        self.placeHolderString = placeHolder;
        self.locationIndex = 0;
        
        self.delegate = self;
        self.keyboardType = UIKeyboardTypeNumberPad;//键盘类型
        self.font = [UIFont systemFontOfSize:20.0];
        self.tintColor = [UIColor grayColor];//光标颜色
        
        //左侧填充视图
        UIView *view = [[UIView alloc]initWithFrame:CGRectMake(0, 0, placeHolderLeft, frame.size.height)];
        self.leftView = view;
        self.leftViewMode = UITextFieldViewModeAlways;
        
        //如果frame存在0,则不做处理
        if (frame.size.width != 0 && frame.size.height != 0) {
            [self loadCustomViewWithPlaceHolder:self.placeHolderString];
            
        }
        
        
    }
    
    return self;
}

- (instancetype)initWithFrame:(CGRect)frame withPlaceHolder:(NSString*)placeHolder withSeparateArray:(NSArray*)countArray
{
    self = [super initWithFrame:frame];
    
    if (self) {
        
        self.separateArray = [NSMutableArray arrayWithArray:countArray];
        self.viewFrame = frame;
        self.placeHolderString = placeHolder;
        
        self.delegate = self;
        self.keyboardType = UIKeyboardTypeNumberPad;//键盘类型
        self.font = [UIFont systemFontOfSize:20.0];
        self.tintColor = [UIColor grayColor];//光标颜色
        
        //左侧填充视图
        UIView *view = [[UIView alloc]initWithFrame:CGRectMake(0, 0, placeHolderLeft, frame.size.height)];
        self.leftView = view;
        self.leftViewMode = UITextFieldViewModeAlways;
        
        //如果frame存在0,则不做处理
        if (frame.size.width != 0 && frame.size.height != 0) {
            [self loadCustomViewWithPlaceHolder:self.placeHolderString];
            
        }
        
        
    }
    
    return self;
}

- (NSString*)userInputContent
{
    NSString *text = self.text;
    
    NSMutableString *mutableText = [NSMutableString stringWithString:text];
    
    NSString *contentStr = [mutableText stringByReplacingOccurrencesOfString:@" " withString:@""];
    
    return contentStr;
}

#pragma mark - 设置frame
- (void)setFrame:(CGRect)frame
{
    [super setFrame:frame];
    
    //frame若存在0,则不处理
    if (frame.size.width == 0 || frame.size.height == 0 ) {
        
        return;
    }
    
    self.viewFrame = frame;
    
    [self loadCustomViewWithPlaceHolder:self.placeHolderString];
    
}

#pragma mark - 构建placeHolder
- (void)loadCustomViewWithPlaceHolder:(NSString*)placeHolder
{
    if (placeHolder) {
        //存在placeHolder文本时,则初始化
        _placeHolderLabel = [[UILabel alloc]init];
        _placeHolderLabel.frame = CGRectMake(placeHolderLeft, 0, self.viewFrame.size.width-placeHolderLeft, self.viewFrame.size.height);
        _placeHolderLabel.text = placeHolder;
        _placeHolderLabel.textColor = [UIColor lightGrayColor];
        [self addSubview:_placeHolderLabel];
        
    }
}

#pragma mark - 光标frame
- (CGRect)caretRectForPosition:(UITextPosition *)position
{
    CGRect originalRect = [super caretRectForPosition:position];
    originalRect.size.height = self.viewFrame.size.height/2;
    originalRect.size.width = 2;
    originalRect.origin.y = self.viewFrame.size.height/4;
    return originalRect;
}


#pragma mark - textField代理
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
    
    
    if (![string isEqualToString:@""]) {
        
        //输入只要不是删除键,则把自定义的placeHolder隐藏了
        self.placeHolderLabel.hidden = YES;
        
        //处理之后的字符串
        NSString *dealString = [self changeStringWithOperateString:string withOperateRange:range withOriginString:textField.text];
        
        textField.text = dealString;
        
    }
    
    
    if ([string isEqualToString:@""] && range.location == 0 && range.length == 1 && textField.text.length == 0) {
        
        //输入删除键后,没有字符了,把自定义的placeHolder显示了
        self.placeHolderLabel.hidden = NO;
        
    }
    
    
    if ([string isEqualToString:@""]) {
        
        //处理之后的字符串
        NSString *dealString = [self changeStringWithOperateString:string withOperateRange:range withOriginString:textField.text];
        
        textField.text = dealString;
    }
    
    //设置光标位置
    [self setSelectedRange:NSMakeRange(self.locationIndex, 0)];
    
    return NO;
}




#pragma mark - 设置光标

- (void) setSelectedRange:(NSRange) range
{
    UITextPosition* beginning = self.beginningOfDocument;
    
    UITextPosition* startPosition = [self positionFromPosition:beginning offset:range.location];
    UITextPosition* endPosition = [self positionFromPosition:beginning offset:range.location + range.length];
    UITextRange* selectionRange = [self textRangeFromPosition:startPosition toPosition:endPosition];
    
    [self setSelectedTextRange:selectionRange];
}


#pragma mark - 核心处理方法

- (NSString*)changeStringWithOperateString:(NSString*)string withOperateRange:(NSRange)range withOriginString:(NSString*)originString
{
    
    self.locationIndex = range.location;
    
    //原始字符串
    NSMutableString *originStr = [NSMutableString stringWithString:originString];
    
    //截取操作的位置之前的字符串
    NSMutableString *subStr = [NSMutableString stringWithString:[originStr substringToIndex:range.location]];
    //光标前的字符串 剔除空格符号
    NSString *subNoSpace = [subStr stringByReplacingOccurrencesOfString:@" " withString:@""];
    
    //得到操作处前面 空格的总数目
    NSInteger originSpaceCount = subStr.length-subNoSpace.length;
    
    if ([string isEqualToString:@""]) {
        
        //删除字符
        [originStr deleteCharactersInRange:range];
        
    }else{
        
        
        NSMutableString *originMutableStr = [NSMutableString stringWithString:originString];
        NSString *originNoString = [originMutableStr stringByReplacingOccurrencesOfString:@" " withString:@""];
        if (self.limitCount > 0 && originNoString.length >= self.limitCount) {
            
            return originString;
        }
        
        
        
        //插入字符
        [originStr insertString:string atIndex:range.location];
        
        //插入后,index要加1
        self.locationIndex += 1;
        
    }
    
    NSString *originNoSpaceString = [originStr stringByReplacingOccurrencesOfString:@" " withString:@""];
    
    //原始字符串,全部剔除空格
    NSMutableString *newString = [NSMutableString stringWithString:originNoSpaceString];
    
    
    if (self.separateCount > 0) {
        
        //如果是等量分割
        for (NSInteger i = newString.length; i > 0; i--) {
            
            if (i%self.separateCount == 0) {
                //插入空格符
                [newString insertString:@" " atIndex:i];
            }
        }
        
    }
    
    
    if (self.separateArray.count > 0) {
        
        //应该操作的index
        NSMutableArray *indexArray = [NSMutableArray array];
        
        NSInteger currentIndex = 0;
        
        for (int i = 0; i< self.separateArray.count; i++) {
            
            //从用户设置的数组中取值
            id object = self.separateArray[i];
            
            if ([object isKindOfClass:[NSString class]]) {
                //第n次按照多少个分隔
                NSInteger count = [object integerValue];
                //累加
                currentIndex += count;
                //拿到分割处的index
                NSNumber *indexNumber = [NSNumber numberWithInteger:currentIndex];
                
                //添加到数组中
                [indexArray addObject:indexNumber];
            }
            
        }
        
        
        //倒序插入空格符
        for (NSInteger j = indexArray.count-1; j >=0 ; j--) {
            
            NSNumber *indexObject = indexArray[j];
            
            NSInteger index = [indexObject integerValue];
            
            //不可越界
            if (index < newString.length) {
                
                [newString insertString:@" " atIndex:index];
                
            }
        }
        
        
        
    }
    
    
    NSString *newSubString;
    
    if (self.locationIndex > newString.length) {
        //如果是删除最后一位数字,且数字的左侧为空格时,防止越界
        newSubString = [NSString stringWithFormat:@"%@",newString];
        
        self.locationIndex -= 1 ;
    }else{
        
        //添加字符后,光标的左侧文本
        newSubString = [newString substringToIndex:self.locationIndex];
        
    }
    
    //光标左侧文本
    NSMutableString *newSubMutableString = [NSMutableString stringWithString:newSubString];
    
    //将操作后的左侧文本 剔除空格
    NSString *newNoSpaceString = [newSubMutableString stringByReplacingOccurrencesOfString:@" " withString:@""];
    
    //操作后的左侧文本,空格的数量
    NSInteger newSpaceCount = newSubString.length - newNoSpaceString.length;
    
    //如果操作前的空格数量等于操作后的空格数量
    if (originSpaceCount == newSpaceCount) {
        
        
        if ([string isEqualToString:@""]) {
            
            //删除的时候,如果删了该数字后,左侧为空格,则需要光标再左移1位
            if (range.location > 0) {
                
                NSString *originSubS = [originStr  substringWithRange:NSMakeRange(range.location-1, 1)];
                
                if ([originSubS isEqualToString:@" "]) {
                    
                    self.locationIndex -= 1;
                }
            }
            
        }
        
    }else{
        
        //如果操作前的空格数量不等于操作后的空格数量,说明新增文本前,又添加了空格,需要将光标右移1位
        if ([string isEqualToString:@""]) {
            
            
        }else{
            self.locationIndex += 1;
            
        }
        
    }
    
    
    return newString;
}


@end

 

调用:

//
//  ViewController.m
//  CustomTextField
//
//  Created by Doman on 2017/6/12.
//  Copyright © 2017年 Doman. All rights reserved.
//

#import "ViewController.h"
#import "CustomTextField.h"

@interface ViewController ()
{
    CustomTextField *TFOne;
    CustomTextField *TFTwo;
    CustomTextField *TFThree;

}
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    //固定4个进行分隔
    TFOne = [[CustomTextField alloc]initWithFrame:CGRectMake(20, 100, 300, 50) withPlaceHolder:@"请输入银行卡号" withSeparateCount:4];
    TFOne.limitCount = 19;//可以不设置,但是那样的话,就可以无限输入了
    TFOne.layer.cornerRadius = 4.0;
    TFOne.layer.borderColor = [UIColor lightGrayColor].CGColor;
    TFOne.layer.borderWidth = 2.0;
    [self.view addSubview:TFOne];
    
    
    //按照数组中的进行分隔,假如分隔电话号码@[@"3",@"4",@"4"]即可
    TFTwo = [[CustomTextField alloc]initWithFrame:CGRectMake(20, 200, 300, 50) withPlaceHolder:@"请输入电话号码" withSeparateArray:@[@"3",@"4",@"4"]];
    TFTwo.limitCount = 11;//可以不设置,但是那样的话,就可以无限输入了
    TFTwo.layer.cornerRadius = 4.0;
    TFTwo.layer.borderColor = [UIColor lightGrayColor].CGColor;
    TFTwo.layer.borderWidth = 2.0;
    [self.view addSubview:TFTwo];
    
    
    //输入身份证号
    TFThree = [[CustomTextField alloc]initWithFrame:CGRectMake(20, 300, 300, 50) withPlaceHolder:@"请输入身份证号" withSeparateArray:@[@"6",@"8",@"4"]];
    TFThree.limitCount = 18;//可以不设置,但是那样的话,就可以无限输入了
    TFThree.layer.cornerRadius = 4.0;
    TFThree.layer.borderColor = [UIColor lightGrayColor].CGColor;
    TFThree.layer.borderWidth = 2.0;
    [self.view addSubview:TFThree];
    
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    NSLog(@"实际输入银行卡内容:%@",TFOne.userInputContent);
    
    NSLog(@"实际输入电话内容:%@",TFTwo.userInputContent);
    
    NSLog(@"实际输入身份证号内容:%@",TFThree.userInputContent);
}


- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}


@en

demo地址:https://github.com/domanc/CustomTextField.git

 

posted @ 2017-06-12 15:51  iOS_Doman  阅读(674)  评论(0编辑  收藏  举报