BYPhoneNumTF 一个电话号码格式的文本框
功能
当在TextField
输入数字时,会自动分隔为:137 9922 2299 或 137-9922-2299
限制文本输入个数
限制只能输入数字
效果:
实现方法
要实现电话号码格式的输入看似简单,但是实现起来坑非常多,至于坑是什么只有各位动手写了才能体会~
下面我们来实现该功能:
首先要遵守协议<UITextFieldDelegate>
然后在- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
方法中实现我们的逻辑
代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149
| #import "LoginVC.h"
#define placeholder @" "
@interface LoginVC () <UITextFieldDelegate>
@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显得太臃肿了,所以我对代码进行了封装:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| // // 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 <UIKit/UIKit.h>
// @" " or @"-" #define placeholder @" "
@interface BYPhoneNumTF : UITextField
/** 去掉格式的电话号码 */ @property (nonatomic, strong) NSString *plainPhoneNum;
@end
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168
| // // BYPhoneNumTF.m // dev-Jack // // Created by BY on 16/12/2. // Copyright © 2016年 Jack. All rights reserved. //
#import "BYPhoneNumTF.h"
@interface BYPhoneNumTF ()<UITextFieldDelegate>
@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