日常开发中可能有个需求, 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 = ; @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

UITextFeild银行卡/身份证/电话号任意分割.的更多相关文章

  1. C++ VC实现对话框窗口任意分割

    最近写MFC的程序,想在对话框里实现窗口的任意分割.现在网络资料一大抄,找个东西实在麻烦.总算这个很简单,很快就搞定了,写下来做个笔记.    个人认为简单问题最好就是直接贴源代码,一看就明白,说来说 ...

  2. 身份证&银行卡识别方案

    一.  调用第三方服务 腾讯云OCR识别: 实现方法:Post图片 URL到腾讯云服务器.Post图片文件 到腾讯云服务器 b.    报价: 月接口调用总量 0<调用量≤1000 1000&l ...

  3. 银行卡验证API

    一.银联开放平台 https://open.unionpay.com/tjweb/api/detail?apiSvcId=21 应用场景 综合数据服务平台是银联为接入商户提供的综合数据认证服务接口,目 ...

  4. MFC 窗口分割与通信

    一.关于CSplitterWnd类我们在使用CuteFtp或者NetAnt等工具的时候,一般都会被其复杂的界面所吸引,在这些界面中窗口被分割为若干的区域,真正做到了窗口的任意分割. 那么我们自己如何创 ...

  5. 【腾讯Bugly干货分享】深度学习在OCR中的应用

    本文来自于腾讯bugly开发者社区,未经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/5809bb47cc5e52161640c5c8 Dev Club 是一个交流移动 ...

  6. 深入浅出了解OCR识别票据原理

    欢迎大家前往云加社区,获取更多腾讯海量技术实践干货哦~ 译者:Mr.Geek 本文翻译自dzone 中Ivan Ozhiganov所发文章Deep Dive Into OCR for Receipt ...

  7. python模块部分 re模块 之正则表达式

    python 全栈开发 1.什么是模块 2.正则表达式 一.什么是模块? 1.模块: 是一组功能的集合 你要和一个东西打交道,但是这个东西本身和python没有关系,这个东西本身就存在, 这时,pyt ...

  8. 可视化工具solo show-----Prefuse自带例子GraphView讲解

    2014.10.15日以来的一个月,挤破了头.跑断了腿.伤透了心.吃够了全国最大餐饮连锁店——沙县小吃.其中酸甜苦辣,绝不是三言两语能够说得清道的明的.校招的兄弟姐妹们,你们懂得…… 体会最深的一句话 ...

  9. MySQL数据类型(四)

    一.数据类型 二.整型类型 tinyInt: 1个字节:-128-127(有符号) 是否有符号,可以定义时,使用unsign标识,表示无符号的,不写表示有符号的 Create table studen ...

随机推荐

  1. composer update 提示 username

    解决办法 暂时修改composer.json "repositories": { "packagist": { "type": " ...

  2. 如何从MTK机器的NVRAM中获取WIFI mac地址

    在MTK的机器中,如果不用特定的工具烧写MAC地址,在开机后打开WIFI后会显示: "NVRAM WARNING: Err=0x10" 这就是没有烧写mac地址的原因,所以每次打开 ...

  3. HDU3335 Divisibility Dilworth定理+最小路径覆盖

    首先需要一些概念: 有向图,最小路径覆盖,最大独立集,Dilworth,偏序集,跳舞链(DLX).... 理解一: 对于DAG图,有:最大独立集=点-二分匹配数,二分匹配数=最小路径覆盖. 而无向图, ...

  4. Mac OS下面安装mysql以及mysql常用命令

    使用brew安装mysql brew install mysql 安装成功后使用下面命令启动/关闭服务 brew services start mysql brew services stop mys ...

  5. 关于SSL的error问题

    今天模拟网页版微信登录的时候又碰到一个SSLError的问题 requests.exceptions.SSLError: [Errno 1] _ssl.c:503: error:14090086:SS ...

  6. Documentation/kobject.txt翻译--sysfs

    你从未想过的关于kobjects,ksets和ktypes的一切:作者:Greg Kroah-Hartman <gregkh@linuxfoundation.org>:上次更新时间:200 ...

  7. Spring Boot 报错:Error creating bean with name 'entityManagerFactory' defined in class path resource

    spring boot 写一个web项目,在使用spring-data-jpa的时候,启动报如下错误: Error starting ApplicationContext. To display th ...

  8. linux之 CentOS/RHEL/Scientific Linux 6 & 7上安装Telnet

    声明: 在安装和使用Telnet之前,需要记住以下几点. 在公网(WAN)中使用Telnet是非常不好的想法.它会以明文的格式传输登入数据.每个人都可以看到明文.如果你还是需要Telnet,强烈建议你 ...

  9. xshell 用密钥登录服务器

    来源:http://coolnull.com/3510.html 说明:ssh登录提供两种认证方式:口令(密码)认证方式和密钥认证方式.其中口令(密码)认证方式是我们最常用的一种,这里介绍密钥认证方式 ...

  10. redhat 防火墙禁止允许的IP链接指定的端口

    编辑:iptables -A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp -s 192.168.4.3 --dport 80 -j A ...