iOS中對(duì)文本的字符限制示例詳解
需求
1.對(duì)于文本框,字?jǐn)?shù)限制是一種很常見的需求,判斷text.length 即可,然而交互提出了對(duì)字符限制,一個(gè)英文、一個(gè)數(shù)字 對(duì)應(yīng)一個(gè)字符,一個(gè)漢字 對(duì)應(yīng) 兩個(gè)字符,并只可以輸入中英文數(shù)字。so what,要腫么辦呢?
知識(shí)儲(chǔ)備
- TextField
- lengthOfBytesUsingEncoding 方法
- characterAtIndex
首先,對(duì)于正常字?jǐn)?shù)限制的一些操作此處就不講解了。
方法如下
我們需要監(jiān)聽textfield
[textfield addTarget:self action:@selector(textFieldTextEditingChanged:) forControlEvents:UIControlEventEditingChanged];
那么,我們?yōu)槭裁床挥?textfield代理方法
-(BOOL) textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string;
對(duì)于字符計(jì)算來說,使用中文聯(lián)想詞容易產(chǎn)生誤差,并且有些情況并不會(huì)走上述協(xié)議方法,此處沒有深究。
- (void)textFieldTextEditingChanged:(UITextField *)field
{
//不支持系統(tǒng)表情的輸入
if ([[textField textInputMode] primaryLanguage]==nil||[[[textField textInputMode] primaryLanguage]isEqualToString:@"emoji"]) {
return;
}
//中英文數(shù)字判斷
NSString *strig =[[NSString alloc]initWithString:textField.text];
[strig enumerateSubstringsInRange:NSMakeRange(0, strig.length) options:NSStringEnumerationByComposedCharacterSequences usingBlock:^(NSString * _Nullable substring, NSRange substringRange, NSRange enclosingRange, BOOL * _Nonnull stop) {
if (substring.length >=2) {
textField.text =[textField.text stringByReplacingOccurrencesOfString:substring withString:@""];
}
}];
NSString *toBeString = textField.text;
NSString *lastString;
if(toBeString.length>0){
lastString=[toBeString substringFromIndex:toBeString.length-1];
if ([self isInputRuleAndNumber:lastString] != YES) {
textField.text = [toBeString substringToIndex:toBeString.length-1];
}
}
if (textField.text.length == 0) {
return;
}
NSString *lang = [textField.textInputMode primaryLanguage]; // 鍵盤輸入模式
if ([lang isEqualToString:@"zh-Hans"]) { // 簡(jiǎn)體中文輸入,包括簡(jiǎn)體拼音,健體五筆,簡(jiǎn)體手寫
UITextRange *selectedRange = [textField markedTextRange];
//獲取高亮部分
UITextPosition *position = [textField positionFromPosition:selectedRange.start offset:0];
// 沒有高亮選擇的字,則對(duì)已輸入的文字進(jìn)行字?jǐn)?shù)統(tǒng)計(jì)和限制
if (!position) {
if ([self unicodeLengthOfString:textField.text] > kMaxLength){
[self saveOKText:textField.text];
return;
}
}
// 有高亮選擇的字符串,則暫不對(duì)文字進(jìn)行統(tǒng)計(jì)和限制
else{
}
}else{ // 中文輸入法以外的直接對(duì)其統(tǒng)計(jì)限制即可,不考慮其他語種情況
if ([self unicodeLengthOfString:textField.text] > kMaxLength) {
[self saveOKText:textField.text];
return;
}
}
}
上述方法 ,調(diào)用了三個(gè)重要方法
isInputRuleAndNumber 此方法對(duì)于 手寫時(shí)出現(xiàn)的一些圖案沒有剔除
#pragma mark - 謂詞條件限制
/**
pattern中,輸入需要驗(yàn)證的通過的字符
小寫a-z
大寫A-Z
漢字\u4E00-\u9FA5
數(shù)字\u0030-\u0039
@param str 要過濾的字符
@return YES 只允許輸入字母和漢字
*/
- (BOOL)isInputRuleAndNumber:(NSString *)str {
NSString *pattern = @"[a-zA-Z\u4E00-\u9FA5\\u0030-\\u0039]";
NSPredicate *pred = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", pattern];
BOOL isMatch = [pred evaluateWithObject:str];
return isMatch;
}
字符計(jì)算 unicodeLengthOfString
參考iOS textField限制字符串長(zhǎng)度 字符數(shù)
-(NSUInteger)unicodeLengthOfString:(NSString *) text {
NSUInteger asciiLength = 0;
for (NSUInteger i = 0; i < text.length; i++) {
unichar uc = [text characterAtIndex: i];
asciiLength += isascii(uc) ? 1 : 2;
}
return asciiLength;
}
當(dāng)時(shí)想,當(dāng) 字符數(shù)大于 最大字符數(shù) 就把 當(dāng)前textField.text.length 減一取值,但是對(duì)于粘貼復(fù)制 超過 字符數(shù)不止一個(gè)長(zhǎng)度時(shí),就出現(xiàn)問題了。那么我們?nèi)绾谓鉀Q呢?
此處,我想到了使用遞歸,先判斷,最后一個(gè)str,利用unicodeLengthOfString 我們就可以知道 最后str 的字符長(zhǎng)度,不論是 字母、數(shù)字還是漢字,對(duì)于超出的字符數(shù),進(jìn)行判斷,刪除多余長(zhǎng)度。
- (void )saveOKText:(NSString *)textStr
{
int overLength = (int)[self unicodeLengthOfString:textStr] - kMaxLength;//超出的字符數(shù)
if (overLength <= 0 ){
_field.text = textStr;
return;
}
NSString *lastStr = [textStr substringFromIndex:textStr.length-1];
if ([self unicodeLengthOfString:lastStr] >= 2) {
textStr = [textStr substringToIndex:textStr.length-1];
NSLog(@"%@",textStr);
if (overLength >0) {
NSLog(@"%@",textStr);
[self saveOKText:textStr];
}else{
_field.text = textStr;
return;
}
}else if ([self unicodeLengthOfString:lastStr] == 1) {
textStr = [textStr substringToIndex:textStr.length-1];
if (overLength >0) {
[self saveOKText:textStr];
}else{
_field.text = textStr;
return;
}
}
}
其實(shí),對(duì)于此處判斷來說,不用再去判斷字母、數(shù)字還是漢字,對(duì)于超出的字符數(shù),遞歸刪除就好。
此方法 只適用于 中英文的輸入,如果還需要輸入表情,此方法就不適用了。
還有前面提到的 知識(shí)儲(chǔ)備中的方法:
- (NSUInteger)lengthOfBytesUsingEncoding:(NSStringEncoding)enc
按照編碼返回字節(jié)數(shù)
Unicode:
0x00-0x7F的字符,用單個(gè)字節(jié)來表示;
0x80-0x7FF的字符用兩個(gè)字節(jié)表示;
0x800-0xFFFF的字符用3字節(jié)表示;
漢字的unicode范圍是:0x4E00~0x9FA5
一個(gè)漢字 三個(gè)字符,不符合需求。
- (unichar)characterAtIndex:(NSUInteger)index
返回字符
isascii是C語言中的字符檢測(cè)函數(shù)。通常用于檢查參數(shù)c是否為ASCII 碼字符,也就是判斷c 的范圍是否在0 到127 之間。
unichar uc = [text characterAtIndex: i]; asciiLength += isascii(uc) ? 1 : 2;
數(shù)字、字母 的ascii碼值 都在 0-127 之間,字符為1,其他為2。
textView 使用的時(shí)候類似。
總結(jié)
以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問大家可以留言交流,謝謝大家對(duì)腳本之家的支持。
- IOS 中CATextLayer繪制文本字符串
- iOS實(shí)現(xiàn)富文本編輯器的方法詳解
- 解決iOS UITextField 編輯時(shí)文本偏移問題
- iOS App開發(fā)中擴(kuò)展RCLabel組件進(jìn)行基于HTML的文本布局
- iOS使用runtime修改文本框(TextField)的占位文字顏色
- iOS中添加文本鏈接和圖片示例代碼
- IOS判斷字符串是不是純數(shù)字的方法總結(jié)
- iOS中如何判斷中英文混合的字符長(zhǎng)度
- iOS UITextField最大字符數(shù)和字節(jié)數(shù)的限制詳解
- IOS判斷字符串是否有空格實(shí)例
相關(guān)文章
iOS程序開發(fā)之使用PlaceholderImageView實(shí)現(xiàn)優(yōu)雅的圖片加載效果
這篇文章主要介紹了ioS程序開發(fā)之使用PlaceholderImageView實(shí)現(xiàn)優(yōu)雅的圖片加載效果的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2016-09-09
IOS 開發(fā)APP之關(guān)于時(shí)間處理詳細(xì)介紹
這篇文章主要介紹了IOS 開發(fā)APP之關(guān)于時(shí)間處理詳細(xì)介紹的相關(guān)資料,開發(fā)APP 不僅需要對(duì)API的調(diào)用還需要對(duì)時(shí)間相關(guān)的各種API之間的差別,再因場(chǎng)景而異去設(shè)計(jì)相應(yīng)的機(jī)制,需要的朋友可以參考下2016-12-12
iOS 無卡頓同時(shí)使用圓角、陰影和邊框的實(shí)現(xiàn)
這篇文章主要介紹了iOS 無卡頓同時(shí)使用圓角、陰影和邊框的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-01-01
詳解iOS - ASIHTTPRequest 網(wǎng)絡(luò)請(qǐng)求
本篇文章主要介紹了iOS - ASIHTTPRequest 網(wǎng)絡(luò)請(qǐng)求 ,詳細(xì)的介紹了 ASIHTTPRequest的使用,具有一定的參考價(jià)值,有興趣的可以了解一下。2016-12-12
Objective-C 代碼與Javascript 代碼相互調(diào)用實(shí)例
這篇文章主要介紹了Objective-C 代碼與Javascript 代碼相互調(diào)用實(shí)例的相關(guān)資料,現(xiàn)在的APP 應(yīng)用有時(shí)候會(huì)調(diào)用網(wǎng)頁上的內(nèi)容,為了增加用戶體驗(yàn),這里寫下個(gè)實(shí)例,需要的朋友可以參考下2016-10-10
iOS中讓多個(gè)cell上都出現(xiàn)倒計(jì)時(shí)的分析與實(shí)現(xiàn)
這篇文章主要給大家介紹了在iOS中每個(gè)cell上都出現(xiàn)倒計(jì)時(shí)的分析與實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面跟著小編一起來學(xué)習(xí)學(xué)習(xí)吧。2017-07-07
詳解iOS App中UiTabBarController組件的基本用法
UiTabBarController組件即是用來創(chuàng)建App中的Tab視圖切換選項(xiàng)欄,下面將詳解iOS App中UiTabBarController組件的基本用法,包括左右滑動(dòng)切換標(biāo)簽頁等基本功能的實(shí)現(xiàn),需要的朋友可以參考下2016-05-05

