最近开发设置昵称功能的时候遇到一个问题,需要对textfield中中英文字数进行限制,并且中文的长度算作2,显然直接使用[string length]是不行了。相信很多同仁也都遇到过这个问题。那就不墨迹啦,直接上代码吧。
首先,扩展NSString,增加对中文的判断,代码如下
@interface NSString (Chinese)
- (BOOL)isChinese;
@end
@implementation NSString (Chinese)
- (BOOL)isChinese
{
NSString *match = @"(^[\u4e00-\u9fa5]+$)";
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF matches %@", match];
return [predicate evaluateWithObject:self];
}
@end
对UITextField的Delegate方法进行处理,
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
NSMutableString *originalText = [NSMutableString stringWithString:textField.text];
__block NSInteger originalTextLength = 0;
//如果是替换操作,则把需要替换的substring删除
if (range.length > 0) {
[originalText deleteCharactersInRange:range];
}
//枚举原始string中的每一个字符,计算此原始string的长度,这部分string是不需要改变的
[originalText enumerateSubstringsInRange:NSMakeRange(0, originalText.length) options:NSStringEnumerationByComposedCharacterSequences usingBlock:^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) {
//如果是中文,就是将长度*2
if ([substring isChinese]) {
originalTextLength += [substring length] * 2;
} else {
originalTextLength += [substring length];
}
}];
__block BOOL overrange = NO;
//如果是替换操作,这里的string是替换的字符串,如果不是替换操作,这里的string是增加的字符串。枚举这部分string中的每一个字符,进行特殊处理
[string enumerateSubstringsInRange:NSMakeRange(0, string.length) options:NSStringEnumerationByComposedCharacterSequences usingBlock:^(NSString * _Nullable substring, NSRange substringRange, NSRange enclosingRange, BOOL * _Nonnull stop) {
//同上
if ([substring isChinese]) {
originalTextLength += [substring length] * 2;
} else {
originalTextLength += [substring length];
}
//如果字符串长度在限制范围内,就将枚举的字符添加到原始string中,否则认为是超越了长度限制并停止枚举
if (originalTextLength <= TEXTFIELD_INPUTCHAR_MAX_COUNT) {
[originalText appendString:substring];
} else {
overrange = YES;
*stop = YES;
}
}];
//如果上面超出了长度限制,就将调整后的string重新设置到textfield中
if (overrange) {
textField.text = originalText;
return NO;
}
return YES;
}
最后,只需要定义你自己的字数限制TEXTFIELD_INPUTCHAR_MAX_COUNT就可以了。