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 = ; @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银行卡/身份证/电话号任意分割.的更多相关文章
- C++ VC实现对话框窗口任意分割
最近写MFC的程序,想在对话框里实现窗口的任意分割.现在网络资料一大抄,找个东西实在麻烦.总算这个很简单,很快就搞定了,写下来做个笔记. 个人认为简单问题最好就是直接贴源代码,一看就明白,说来说 ...
- 身份证&银行卡识别方案
一. 调用第三方服务 腾讯云OCR识别: 实现方法:Post图片 URL到腾讯云服务器.Post图片文件 到腾讯云服务器 b. 报价: 月接口调用总量 0<调用量≤1000 1000&l ...
- 银行卡验证API
一.银联开放平台 https://open.unionpay.com/tjweb/api/detail?apiSvcId=21 应用场景 综合数据服务平台是银联为接入商户提供的综合数据认证服务接口,目 ...
- MFC 窗口分割与通信
一.关于CSplitterWnd类我们在使用CuteFtp或者NetAnt等工具的时候,一般都会被其复杂的界面所吸引,在这些界面中窗口被分割为若干的区域,真正做到了窗口的任意分割. 那么我们自己如何创 ...
- 【腾讯Bugly干货分享】深度学习在OCR中的应用
本文来自于腾讯bugly开发者社区,未经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/5809bb47cc5e52161640c5c8 Dev Club 是一个交流移动 ...
- 深入浅出了解OCR识别票据原理
欢迎大家前往云加社区,获取更多腾讯海量技术实践干货哦~ 译者:Mr.Geek 本文翻译自dzone 中Ivan Ozhiganov所发文章Deep Dive Into OCR for Receipt ...
- python模块部分 re模块 之正则表达式
python 全栈开发 1.什么是模块 2.正则表达式 一.什么是模块? 1.模块: 是一组功能的集合 你要和一个东西打交道,但是这个东西本身和python没有关系,这个东西本身就存在, 这时,pyt ...
- 可视化工具solo show-----Prefuse自带例子GraphView讲解
2014.10.15日以来的一个月,挤破了头.跑断了腿.伤透了心.吃够了全国最大餐饮连锁店——沙县小吃.其中酸甜苦辣,绝不是三言两语能够说得清道的明的.校招的兄弟姐妹们,你们懂得…… 体会最深的一句话 ...
- MySQL数据类型(四)
一.数据类型 二.整型类型 tinyInt: 1个字节:-128-127(有符号) 是否有符号,可以定义时,使用unsign标识,表示无符号的,不写表示有符号的 Create table studen ...
随机推荐
- avalon 搭配 百度的UI移动框架 gmu 可以很好干活
使用过的人评价, 这个UI稳定, bug少, 组件丰富, 触屏好; 小公司, 可以用用 链接
- vue url生产二维码
<template> <div id="QRcode"> <div class='QR-qrcode' style='display:none;'&g ...
- 20165212 2017-2018-2《Java程序设计》课程总结
20165212 2017-2018-2<Java程序设计>课程总结 作业链接汇总 每周作业链接 预备作业1:我期望的师生关系 预备作业2:做中学learning by doing个人感想 ...
- TCP滑动窗口与回退N针协议
[转]TCP 滑动窗口协议/1比特滑动窗口协议/后退n协议/选择重传协议 2014-1-5阅读884 评论0 本文转自 http://www.cnblogs.com/ulihj/archive/201 ...
- [TopCoder11557]MatrixPower
vjudge description 你有一个\(n \times n\)的矩阵\(A\),下标从\(0\)开始,其中\(A_{i,j}=di + q^j\). 给你\(d,q,n,k,s,t\),求 ...
- linux sort 多列正排序,倒排序
转载:https://segmentfault.com/a/1190000005713784 sort是在Linux里非常常用的一个命令,管排序 sort将文件的每一行作为一个单位,相互比较,比较原则 ...
- Android实现带图标的ListView
版权声明:本文为博主原创文章.未经博主同意不得转载. https://blog.csdn.net/bear_huangzhen/article/details/23991119 Android实现带图 ...
- Git核心概念
Git作为流行的分布式版本管理系统,用好它要理解下面几个核心的概念. 1.Git保寸的是文件完整快照,而不是差异变化或者文件补丁.每次提交若文件有变化则会指向上一个版本的指针而不重复生成副本. Git ...
- erlang单独配置文件
一种是erl启动的时候加参数 doudizhu.config [ {doudizhu,[ {listen_port, }, {node_caller_prefix,"ruby"}, ...
- ANSI和UNICODE编程的注意事项
建立UNICODE编码工程 在VC60下,默认方式下建立的是ANSI编码的工程(注:编译的exe内部,其资源字符是以UNICODE保存),建立UNICODE编码工程的方法: 1.为工程添加UNICOD ...