实现一个实现电话号码格式的文本框
功能
当在TextField
输入数字时,会自动分隔为:137 9922 2299 或 137-9922-2299
限制文本输入个数
限制只能输入数字
效果:
实现方法
要实现电话号码格式的输入看似简单,但是实现起来坑非常多,至于坑是什么只有各位动手写了才能体会~
下面我们来实现该功能:
首先要遵守协议
然后在- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
方法中实现我们的逻辑
代码:
#import "LoginVC.h"
#define placeholder @" "
@interface LoginVC ()
@property (weak, nonatomic) IBOutlet UITextField *phoneNumberTF;
@end
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
NSString *phStr = placeholder;
unichar phChar = ' ';
if (phStr.length) {
phChar = [phStr characterAtIndex:0];
}
if (textField) {
NSString* text = textField.text;
//删除
if([string isEqualToString:@""]){
//删除一位
if(range.length == 1){
//最后一位,遇到空格则多删除一次
if (range.location == text.length - 1 ) {
if ([text characterAtIndex:text.length - 1] == phChar) {
[textField deleteBackward];
}
return YES;
}
//从中间删除
else{
NSInteger offset = range.location;
if (range.location < text.length && [text characterAtIndex:range.location] == phChar && [textField.selectedTextRange isEmpty]) {
[textField deleteBackward];
offset --;
}
[textField deleteBackward];
textField.text = [self _parseString:textField.text];
UITextPosition *newPos = [textField positionFromPosition:textField.beginningOfDocument offset:offset];
textField.selectedTextRange = [textField textRangeFromPosition:newPos toPosition:newPos];
return NO;
}
}
else if (range.length > 1) {
BOOL isLast = NO;
//如果是从最后一位开始
if(range.location + range.length == textField.text.length ){
isLast = YES;
}
[textField deleteBackward];
textField.text = [self _parseString:textField.text];
NSInteger offset = range.location;
if (range.location == 3 || range.location == 8) {
offset ++;
}
if (isLast) {
//光标直接在最后一位了
}else{
UITextPosition *newPos = [textField positionFromPosition:textField.beginningOfDocument offset:offset];
textField.selectedTextRange = [textField textRangeFromPosition:newPos toPosition:newPos];
}
return NO;
}
else{
return YES;
}
}
else if(string.length >0){
//限制输入字符个数
if (([self _noneSpaseString:textField.text].length + string.length - range.length > 11) ) {
return NO;
}
//判断是否是纯数字(搜狗,百度输入法,数字键盘居然可以输入其他字符)
if(![self _isNum:string]){
return NO;
}
[textField insertText:string];
textField.text = [self _parseString:textField.text];
NSInteger offset = range.location + string.length;
if (range.location == 3 || range.location == 8) {
offset ++;
}
UITextPosition *newPos = [textField positionFromPosition:textField.beginningOfDocument offset:offset];
textField.selectedTextRange = [textField textRangeFromPosition:newPos toPosition:newPos];
return NO;
}else{
return YES;
}
}
return YES;
}
- (NSString*)_parseString:(NSString*)string{
if (!string) {
return nil;
}
NSMutableString* mStr = [NSMutableString stringWithString:[string stringByReplacingOccurrencesOfString:placeholder withString:@""]];
if (mStr.length >3) {
[mStr insertString:placeholder atIndex:3];
}if (mStr.length > 8) {
[mStr insertString:placeholder atIndex:8];
}
return mStr;
}
/** 获取正常电话号码(去掉空格) */
- (NSString*)_noneSpaseString:(NSString*)string{
return [string stringByReplacingOccurrencesOfString:placeholder withString:@""];
}
- (BOOL)_isNum:(NSString *)checkedNumString {
if (!checkedNumString) {
return NO;
}
checkedNumString = [checkedNumString stringByTrimmingCharactersInSet:[NSCharacterSet decimalDigitCharacterSet]];
if(checkedNumString.length > 0) {
return NO;
}
return YES;
}
封装方法
需要实现的代码就是要这么多,但这些代码写在ViewController显得太臃肿了,所以我对代码进行了封装:
//
// BYPhoneNumTF.h
//
// Created by BY on 16/12/2.
// Copyright © 2016年 BY. All rights reserved.
// 电话号码类型的文本输入框,且只能输入数字
// 输入显示:137 9922 1234 或 137-9922-1234
// 使用方法:在XIB中的TextField继承该类即可
// 修改占位符placeholder即可改变样式
#import
// @" " or @"-"
#define placeholder @" "
@interface BYPhoneNumTF : UITextField
/** 去掉格式的电话号码 */
@property (nonatomic, strong) NSString *plainPhoneNum;
@end
//
// BYPhoneNumTF.m
// dev-Jack
//
// Created by BY on 16/12/2.
// Copyright © 2016年 Jack. All rights reserved.
//
#import "BYPhoneNumTF.h"
@interface BYPhoneNumTF ()
@end
@implementation BYPhoneNumTF
- (NSString *)plainPhoneNum {
return [self _noneSpaseString:self.text];
}
- (void)awakeFromNib {
[super awakeFromNib];
self.delegate = self;
}
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
NSString *phStr = placeholder;
unichar phChar = ' ';
if (phStr.length) {
phChar = [phStr characterAtIndex:0];
}
if (textField) {
NSString* text = textField.text;
//删除
if([string isEqualToString:@""]){
//删除一位
if(range.length == 1){
//最后一位,遇到空格则多删除一次
if (range.location == text.length - 1 ) {
if ([text characterAtIndex:text.length - 1] == phChar) {
[textField deleteBackward];
}
return YES;
}
//从中间删除
else{
NSInteger offset = range.location;
if (range.location < text.length && [text characterAtIndex:range.location] == phChar && [textField.selectedTextRange isEmpty]) {
[textField deleteBackward];
offset --;
}
[textField deleteBackward];
textField.text = [self _parseString:textField.text];
UITextPosition *newPos = [textField positionFromPosition:textField.beginningOfDocument offset:offset];
textField.selectedTextRange = [textField textRangeFromPosition:newPos toPosition:newPos];
return NO;
}
}
else if (range.length > 1) {
BOOL isLast = NO;
//如果是从最后一位开始
if(range.location + range.length == textField.text.length ){
isLast = YES;
}
[textField deleteBackward];
textField.text = [self _parseString:textField.text];
NSInteger offset = range.location;
if (range.location == 3 || range.location == 8) {
offset ++;
}
if (isLast) {
//光标直接在最后一位了
}else{
UITextPosition *newPos = [textField positionFromPosition:textField.beginningOfDocument offset:offset];
textField.selectedTextRange = [textField textRangeFromPosition:newPos toPosition:newPos];
}
return NO;
}
else{
return YES;
}
}
else if(string.length >0){
//限制输入字符个数
if (([self _noneSpaseString:textField.text].length + string.length - range.length > 11) ) {
return NO;
}
//判断是否是纯数字(搜狗,百度输入法,数字键盘居然可以输入其他字符)
if(![self _isNum:string]){
return NO;
}
[textField insertText:string];
textField.text = [self _parseString:textField.text];
NSInteger offset = range.location + string.length;
if (range.location == 3 || range.location == 8) {
offset ++;
}
UITextPosition *newPos = [textField positionFromPosition:textField.beginningOfDocument offset:offset];
textField.selectedTextRange = [textField textRangeFromPosition:newPos toPosition:newPos];
return NO;
}else{
return YES;
}
}
return YES;
}
- (NSString*)_parseString:(NSString*)string{
if (!string) {
return nil;
}
NSMutableString* mStr = [NSMutableString stringWithString:[string stringByReplacingOccurrencesOfString:placeholder withString:@""]];
if (mStr.length >3) {
[mStr insertString:placeholder atIndex:3];
}if (mStr.length > 8) {
[mStr insertString:placeholder atIndex:8];
}
return mStr;
}
/** 获取正常电话号码(去掉空格) */
- (NSString*)_noneSpaseString:(NSString*)string{
return [string stringByReplacingOccurrencesOfString:placeholder withString:@""];
}
- (BOOL)_isNum:(NSString *)checkedNumString {
if (!checkedNumString) {
return NO;
}
checkedNumString = [checkedNumString stringByTrimmingCharactersInSet:[NSCharacterSet decimalDigitCharacterSet]];
if(checkedNumString.length > 0) {
return NO;
}
return YES;
}
@end
使用方法也很简单:
在storyboard中的TextField
控件的Calss类型选择该类BYPhoneNumTF
即可。
代码及Demo下载地址:BYPhoneNumTF