先說說記錄這個(gè)的原因吧腺逛,關(guān)于限制UITextField的輸入字?jǐn)?shù)的各種需求著拭,已經(jīng)疲軟了纱扭,工作幾年中用的還真不少,有只要字?jǐn)?shù)長(zhǎng)度的儡遮,也有字符長(zhǎng)度的乳蛾,當(dāng)然這個(gè)就包括中文和英文,還有.....標(biāo)點(diǎn)符號(hào)也分中文和英文的鄙币,每次都多不情愿的寫這個(gè)地方屡久,閑來無事,就來記錄一下爱榔,方便大家,若有不對(duì)的地方糙及,多多指教哈详幽。關(guān)于UITextField大家肯定對(duì)下面這個(gè)方法非常熟悉- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string那么這個(gè)函數(shù)的大概意思是什么呢?我是這么理解的(個(gè)人認(rèn)為)由于返回的是個(gè) BOOL 所以我猜想大概就是我們?cè)谳斎氲臅r(shí)候浸锨,是否對(duì)UITextField 的內(nèi)容進(jìn)行修改下面來簡(jiǎn)單分析下參數(shù)textField 這個(gè)參數(shù)大家都懂唇聘,就是響應(yīng)該協(xié)議的UITextField對(duì)象range在這個(gè)函數(shù)中,添加了打印信息柱搜,測(cè)試了下- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{? ? ? ? NSLog(@" 打印信息:%lu? -----%lu ",(unsigned long)range.location,(unsigned long)range.length);}//打印log2017-01-25 17:48:49.826 TestObject[5502:683375]? 打印信息toBeString:Zxtgfd2017-01-25 17:48:50.506 TestObject[5502:683375]? 打印信息:6? -----0 2017-01-25 17:48:50.508 TestObject[5502:683375]? 打印信息toBeString:Zxtgfda2017-01-25 17:48:51.894 TestObject[5502:683375]? 打印信息:6? -----1由此可以看到迟郎,在輸入的時(shí)候,range.length為0聪蘸,range.location為插入時(shí)的位置 宪肖,range.length為1時(shí),是我在點(diǎn)擊刪除的時(shí)候打印的健爬,應(yīng)該可以表示刪除(不確定)string string.length為0時(shí)控乾,表示刪除。限制輸入長(zhǎng)度1 如果只是輸入英文狀態(tài)娜遵,或者數(shù)字狀態(tài)蜕衡,那么我們我們可以利用這個(gè)函數(shù),實(shí)現(xiàn)方法為:- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{? ? ? ? NSLog(@" 打印信息:%lu? -----%lu ",(unsigned long)range.location,(unsigned long)range.length);? ? if (textField.text.length + string.length > kMaxNumber) {? ? ? ? return NO;? ? }? ? //刪除按鈕? ? if (string.length == 0)? ? {? ? ? ? return YES;? ? }? ? return YES;}2 但是设拟,如果要涉及到中文的話慨仿,這樣就不行了。因?yàn)槟呻剩谳斎胫形牡臅r(shí)候镰吆,如果你還沒有確定所輸入的中文,那么UITextField此時(shí)接收的并不是中文躲雅,而是對(duì)應(yīng)的拼音鼎姊,比如你想輸入漢字君不見黃河之水天上來 那么對(duì)應(yīng)的拼音則是junbujianhuanghezhishuitianshanglai這么一來,比如你想限制的輸入個(gè)數(shù)為10 那么只能輸入到j(luò)unbujianh這個(gè)位置。那么我們?cè)撛趺唇鉀Q問題呢相寇,進(jìn)入API我們可以發(fā)現(xiàn)慰于。UITextField : UIControl? ---- UITextField繼承自UIControl有如下函數(shù)- (void)addTarget:(nullable id)target action:(SEL)action forControlEvents:(UIControlEvents)controlEvents;typedef NS_OPTIONS(NSUInteger, UIControlEvents) {? ? UIControlEventTouchDown? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? = 1 <<? 0,? ? ? // on all touch downs? ? UIControlEventTouchDownRepeat? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? = 1 <<? 1,? ? ? // on multiple touchdowns (tap count > 1)? ? UIControlEventTouchDragInside? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? = 1 <<? 2,? ? UIControlEventTouchDragOutside? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? = 1 <<? 3,? ? UIControlEventTouchDragEnter? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? = 1 <<? 4,? ? UIControlEventTouchDragExit? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? = 1 <<? 5,? ? UIControlEventTouchUpInside? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? = 1 <<? 6,? ? UIControlEventTouchUpOutside? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? = 1 <<? 7,? ? UIControlEventTouchCancel? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? = 1 <<? 8,? ? UIControlEventValueChanged? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? = 1 << 12,? ? // sliders, etc.? ? UIControlEventPrimaryActionTriggered NS_ENUM_AVAILABLE_IOS(9_0) = 1 << 13,? ? // semantic action: for buttons, etc.? ? UIControlEventEditingDidBegin? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? = 1 << 16,? ? // UITextField? ? UIControlEventEditingChanged? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? = 1 << 17,? ? UIControlEventEditingDidEnd? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? = 1 << 18,? ? UIControlEventEditingDidEndOnExit? ? ? ? ? ? ? ? ? ? ? ? ? ? ? = 1 << 19,? ? // 'return key' ending editing? ? UIControlEventAllTouchEvents? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? = 0x00000FFF,? // for touch events? ? UIControlEventAllEditingEvents? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? = 0x000F0000,? // for UITextField? ? UIControlEventApplicationReserved? ? ? ? ? ? ? ? ? ? ? ? ? ? ? = 0x0F000000,? // range available for application use? ? UIControlEventSystemReserved? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? = 0xF0000000,? // range reserved for internal framework use? ? UIControlEventAllEvents? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? = 0xFFFFFFFF};我們可以利用此函數(shù)和對(duì)應(yīng)的枚舉UIControlEventEditingChanged來監(jiān)測(cè)輸入的內(nèi)容變化,從而控制輸入的字?jǐn)?shù)代碼如下- (void)textFiledDidChange:(UITextField *)textField{? ? if (kMaxNumber == 0) return;? ? NSString *toBeString = textField.text;? ? NSLog(@" 打印信息toBeString:%@",toBeString);? ? NSString *lang = [[textField textInputMode] primaryLanguage]; // 鍵盤輸入模式? ? if ([lang isEqualToString:@"zh-Hans"]) { // 簡(jiǎn)體中文輸入唤衫,包括簡(jiǎn)體拼音婆赠,健體五筆,簡(jiǎn)體手寫? ? ? ? //判斷markedTextRange是不是為Nil佳励,如果為Nil的話就說明你現(xiàn)在沒有未選中的字符休里,? ? ? ? //可以計(jì)算文字長(zhǎng)度。否則此時(shí)計(jì)算出來的字符長(zhǎng)度可能不正確? ? ? ? UITextRange *selectedRange = [textField markedTextRange];? ? ? ? //獲取高亮部分(感覺輸入中文的時(shí)候才有)? ? ? ? UITextPosition *position = [textField positionFromPosition:selectedRange.start offset:0];? ? ? ? // 沒有高亮選擇的字赃承,則對(duì)已輸入的文字進(jìn)行字?jǐn)?shù)統(tǒng)計(jì)和限制? ? ? ? if (!position)? ? ? ? {? ? ? ? ? ? //中文和字符一起檢測(cè)? 中文是兩個(gè)字符? ? ? ? ? ? if ([toBeString getStringLenthOfBytes] > kMaxNumber)? ? ? ? ? ? {? ? ? ? ? ? ? ? textField.text = [toBeString subBytesOfstringToIndex:kMaxNumber];? ? ? ? ? ? }? ? ? ? }? ? }? ? else? ? {? ? ? ? if ([toBeString getStringLenthOfBytes] > kMaxNumber)? ? ? ? {? ? ? ? ? ? textField.text = [toBeString subBytesOfstringToIndex:kMaxNumber];? ? ? ? }? ? }}其中有正則表達(dá)式的驗(yàn)證妙黍,方法我是寫在NSString的擴(kuò)展中的,具體如下//.h文件#import@interface NSString (category)
- (NSInteger)getStringLenthOfBytes;
- (NSString *)subBytesOfstringToIndex:(NSInteger)index;
@end
//.m文件
#import "NSString+category.h"
@implementation NSString (category)
- (NSInteger)getStringLenthOfBytes
{
NSInteger length = 0;
for (int i = 0; i<[self length]; i++) {
//截取字符串中的每一個(gè)字符
NSString *s = [self substringWithRange:NSMakeRange(i, 1)];
if ([self validateChineseChar:s]) {
NSLog(@" s 打印信息:%@",s);
length +=2;
}else{
length +=1;
}
NSLog(@" 打印信息:%@? %ld",s,(long)length);
}
return length;
}
- (NSString *)subBytesOfstringToIndex:(NSInteger)index
{
NSInteger length = 0;
NSInteger chineseNum = 0;
NSInteger zifuNum = 0;
for (int i = 0; i<[self length]; i++) {
//截取字符串中的每一個(gè)字符
NSString *s = [self substringWithRange:NSMakeRange(i, 1)];
if ([self validateChineseChar:s])
{
if (length + 2 > index)
{
return [self substringToIndex:chineseNum + zifuNum];
}
length +=2;
chineseNum +=1;
}
else
{
if (length +1 >index)
{
return [self substringToIndex:chineseNum + zifuNum];
}
length+=1;
zifuNum +=1;
}
}
return [self substringToIndex:index];
}
//檢測(cè)中文或者中文符號(hào)
- (BOOL)validateChineseChar:(NSString *)string
{
NSString *nameRegEx = @"[\\u0391-\\uFFE5]";
if (![string isMatchesRegularExp:nameRegEx]) {
return NO;
}
return YES;
}
//檢測(cè)中文
- (BOOL)validateChinese:(NSString*)string
{
NSString *nameRegEx = @"[\u4e00-\u9fa5]";
if (![string isMatchesRegularExp:nameRegEx]) {
return NO;
}
return YES;
}
- (BOOL)isMatchesRegularExp:(NSString *)regex {
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex];
return [predicate evaluateWithObject:self];
}
@end