iOS文本字数限制处理
2017-04-18 本文已影响63人
阿咿呀嘿
实际开发中经常遇到文本字数限制的需求,比如发布朋友圈时输入正文长度不能超过1000字,输入用户名时限制长度不能超过10个字符。有时要求中文和表情都按照一个字符计数,有时要求按照两个字符计数。甚至,有时还要限制用户名中不能包含除数字、字母、中外外的其他字符。
不同字符的长度
- 英文字符:字符串长度为1,字节长度为1
- 中文字符:字符串长度为1,字节长度为2
- emoji符号:字符串长度可能为2、5、7、11等等,字节长度可能为4、12、18等(emoji可以通过添加控制符进行变体、通过添加链接符进行连接等)
- 其他字符:不同语言的字符各不相同
文本输入控件
- UITextField:通过监听通知UITextFieldTextDidChangeNotification实现在控件文本内容发生变化时进行字数限制判断。再使用代理方法-textField:shouldChangeCharactersInRange:replacementString:配合实现输入控制。
- UITextView:通过代理方法-textViewDidChange:和-textView:shouldChangeTextInRange:replacementText:
通常需要在控件文本内容发生变化时,进行字数限制判断。
统计字符串的字符个数
NSInteger len = text.length;
统计字符串的字节长度
NSStringEncoding enc = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingGB_18030_2000);
NSData *data = [text dataUsingEncoding:enc];
NSInteger dataLen = data.length;
遍历字符串
[text enumerateSubstringsInRange:NSMakeRange(0, text.length) options:NSStringEnumerationByComposedCharacterSequences usingBlock:^(NSString * _Nullable substring, NSRange substringRange, NSRange enclosingRange, BOOL * _Nonnull stop) {
//
}];
UITextView实例
#pragma mark - UITextViewDelegate
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
{
if (text.length == 0) { return YES; }
return textView.text.length < 30;
}
- (void)textViewDidChange:(UITextView *)textView
{
NSString *text = textView.text;
NSInteger c = 30;
if (text.length > c)
{
if (textView.markedTextRange) { return; }
textView.text = [text substringToIndex:c];
}
}
UITextField实例
#pragma mark - UITextField Change Text
- (void)textFieldTextDidChange:(NSNotification *)notification
{
UITextField *textField = notification.object;
NSString *text = textField.text;
NSInteger c = 8;
NSStringEncoding enc = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingGB_18030_2000);
NSData *data = [text dataUsingEncoding:enc];
if (data.length > c)
{
if (textField.markedTextRange) { return; }
NSMutableString *newText = [NSMutableString string];
__block NSInteger count = 0;
[text enumerateSubstringsInRange:NSMakeRange(0, text.length) options:NSStringEnumerationByComposedCharacterSequences usingBlock:^(NSString * _Nullable substring, NSRange substringRange, NSRange enclosingRange, BOOL * _Nonnull stop) {
NSData *da = [substring dataUsingEncoding:enc];
if (da.length <= c - count)
{
[newText appendString:substring];
count += da.length;
}
else
{
*stop = YES;
}
}];
textField.text = newText;
}
}
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
NSLog(@"string:%@, range:%@", string, [NSValue valueWithRange:range]);
if (string.length == 0) { return YES; }
NSStringEncoding enc = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingGB_18030_2000);
NSData *data = [textField.text dataUsingEncoding:enc];
return data.length < 8;
}