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

gif:

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

代码:

继承一个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 = ; @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 = ; self.delegate = self;
self.keyboardType = UIKeyboardTypeNumberPad;//键盘类型
self.font = [UIFont systemFontOfSize:20.0];
self.tintColor = [UIColor grayColor];//光标颜色 //左侧填充视图
UIView *view = [[UIView alloc]initWithFrame:CGRectMake(, , placeHolderLeft, frame.size.height)];
self.leftView = view;
self.leftViewMode = UITextFieldViewModeAlways; //如果frame存在0,则不做处理
if (frame.size.width != && frame.size.height != ) {
[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(, , placeHolderLeft, frame.size.height)];
self.leftView = view;
self.leftViewMode = UITextFieldViewModeAlways; //如果frame存在0,则不做处理
if (frame.size.width != && frame.size.height != ) {
[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 == || frame.size.height == ) { 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, , 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/;
originalRect.size.width = ;
originalRect.origin.y = self.viewFrame.size.height/;
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 == && range.length == && textField.text.length == ) { //输入删除键后,没有字符了,把自定义的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, )]; 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 > && originNoString.length >= self.limitCount) { return originString;
} //插入字符
[originStr insertString:string atIndex:range.location]; //插入后,index要加1
self.locationIndex += ; } NSString *originNoSpaceString = [originStr stringByReplacingOccurrencesOfString:@" " withString:@""]; //原始字符串,全部剔除空格
NSMutableString *newString = [NSMutableString stringWithString:originNoSpaceString]; if (self.separateCount > ) { //如果是等量分割
for (NSInteger i = newString.length; i > ; i--) { if (i%self.separateCount == ) {
//插入空格符
[newString insertString:@" " atIndex:i];
}
} } if (self.separateArray.count > ) { //应该操作的index
NSMutableArray *indexArray = [NSMutableArray array]; NSInteger currentIndex = ; for (int i = ; 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-; j >= ; 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 -= ;
}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 > ) { NSString *originSubS = [originStr substringWithRange:NSMakeRange(range.location-, )]; if ([originSubS isEqualToString:@" "]) { self.locationIndex -= ;
}
} } }else{ //如果操作前的空格数量不等于操作后的空格数量,说明新增文本前,又添加了空格,需要将光标右移1位
if ([string isEqualToString:@""]) { }else{
self.locationIndex += ; } } 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(, , , ) withPlaceHolder:@"请输入银行卡号" withSeparateCount:];
TFOne.limitCount = ;//可以不设置,但是那样的话,就可以无限输入了
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(, , , ) withPlaceHolder:@"请输入电话号码" withSeparateArray:@[@"",@"",@""]];
TFTwo.limitCount = ;//可以不设置,但是那样的话,就可以无限输入了
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(, , , ) withPlaceHolder:@"请输入身份证号" withSeparateArray:@[@"",@"",@""]];
TFThree.limitCount = ;//可以不设置,但是那样的话,就可以无限输入了
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

05-08 15:44