開發(fā)中常遇到字符串輸入長度限制的需求 比如昵稱限制輸入7個字等
因為iOS中字符串的length屬性 計算的是字符的個數(shù)(不論漢字還是字母或者數(shù)字 都算是一個長度)
通常情況下表達相同意思的時候 英文普遍比漢字要長一些
如果直接用length來計算并截取長度 輸入英文時 通常很難表達全意思了
所以有了中文限制7個字 英文對應允許輸入14個字符的需求
下面的方法是NSString 分類中的方法 輸出的結(jié)果是中英文長度全部轉(zhuǎn)換為中文的長度迅诬。
//ASCII碼0.5長度 中文1長度
- (CGFloat)MS_length
{
CGFloat n = [self length];
int l = 0;
int a = 0;
int b = 0;
CGFloat wLen = 0;
unichar c;
for(int i = 0; i < n; i++){
c = [self characterAtIndex:i];//按順序取出單個字符
if(isblank(c)){//判斷字符串為空或為空格
b++;
}else if(isascii(c)){
a++;
}else{
l++;
}
wLen = l+(CGFloat)((CGFloat)(a+b)/2.0);
NSLog(@"wLen--%f",wLen);
}
if(a==0 && l==0)
{
return 0;//只有isblank
}else{
return wLen;//長度楚午,中文占1麦撵,英文等能轉(zhuǎn)ascii的占0.5
}
}
計算好長度以后 接下來就是按照需求截取規(guī)定的字符串
下面是根據(jù)轉(zhuǎn)換過后的長度返回截取后的字符串
- (NSString *)MSSubstringToIndex:(NSUInteger)toIndex{
CGFloat n = [self length];
int l = 0;
int a = 0;
int b = 0;
CGFloat wLen = 0;
unichar c;
for(int i = 0; i < n; i++){
c = [self characterAtIndex:i];//按順序取出單個字符
if(isblank(c)){//判斷字符串為空或為空格
b++;
}else if(isascii(c)){
a++;
}else{
l++;
}
//中文為1 ASCII為0.5 計算出最終長度
wLen = l+(CGFloat)((CGFloat)(a+b)/2.0);
if (wLen >= toIndex) {
break;
}
}
NSString *finalStr;
//以允許輸入7個漢字(14個ASCII字符)為例 如果中英文混合輸入 自動計算長度(中文占倆 英文占一個)
//前面已經(jīng)有13個字符了 第十四個輸入字母時 允許輸入
if (((int)(wLen * 2)) % 2 == 0) {
finalStr = [self substringToIndex:a + b + l];
}else{
//第十四個字符輸入漢字時 不允許輸入了 因為漢字占倆字符 允許輸入的話 就變成15個 超出了14個規(guī)定范圍
finalStr = [self substringToIndex:a + b + l - 1];
}
return finalStr;
}
在需要限制字數(shù)的地方調(diào)用方式如下
如果限制輸入的中文字符串長度為7(英文長度為14 中英可隨意搭配 會自動截取所需長度)
在監(jiān)聽輸入框輸入的方法中添加如下類似的代碼
WEAK
[_nicknameTF.rac_textSignal subscribeNext:^(NSString * _Nullable x) {
STRONG
if (x.MS_length > 7) {
self.nicknameTF.text = [x MSSubstringToIndex:7];
}
}];