iOS UITextField最大字符数和字节数的限制详解

2020-01-18 18:16:56于丽

前言

这里我给大家几组测试用例可以一试,为啥不好用。

     1、限制10个字节,输入2个Emoj之后是8个字节(一个Emoj是4个字节),此时再输入一个中文,看看结果如何(中文的UTF8占3个字节)

     2、限制5个字符,一个Emoj是2个字符,其他都是一个。此时输入两个Emoj,再输入中文,然后中文联想试试。

就目前的情况来说,看了很多资料,并没有一个通用的能限制字符数和字节数的封装。这里全面进行了总结,并进行了封装。欢迎大家下载。

一. 字符限制

1. 错误方法

常见的这种方法是错误的,会导致Emoj表情的截取问题


- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
 if(range.length + range.location > textField.text.length)
 {
 return NO;
 }
 
 NSUInteger newLength = [textField.text length] + [string length] - range.length;
 return newLength <= 5;
}

这种限制方法会导致拼音下出现这种情况,且无法输入.无法输入满5个字符。在emoj表情也有问题

uitextfield,最大长度,uitextfield输入限制,uitextfield限制字数

2. 推荐方法

使用rangeOfComposedCharacterSequencesForRange, 防止在range范围内整词被截断


- (void)textFieldDidChange:(UITextField *)textField
{
 NSString *toBeString = textField.text;

 UITextRange *selectedRange = [textField markedTextRange];
 UITextPosition *position = [textField positionFromPosition:selectedRange.start offset:0];
 
 // 没有高亮选择的字,则对已输入的文字进行字数统计和限制,防止中文被截断
 if (!position){
 if (toBeString.length > _maxLength){
  //中文和emoj表情存在问题,需要对此进行处理
  NSRange rangeRange = [toBeString rangeOfComposedCharacterSequencesForRange:NSMakeRange(0, _maxLength)];
  textField.text = [toBeString substringWithRange:rangeRange];
 }
 }
}

uitextfield,最大长度,uitextfield输入限制,uitextfield限制字数

二. 字节限制

1. 限制字节数

在UTF8中,英文和数字是1个字节,汉子是3个字节,emoji是3或者4个字节。这里的难度比上面更大,如果截取失败,极有可能出现乱码。这里我们的做法如下


- (void)textFieldDidChange:(UITextField *)textField
{
 NSString *toBeString = textField.text;
 //---字节处理
 NSInteger bytesCount = strlen([textField.text UTF8String]);
 if (bytesCount > _maxBytesLength) {
 NSString *content = [textField.text subStrWithUtf8Len:(int)_maxBytesLength];
 textField.text = content;
 }
}

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{
 
 NSString * inputString = [textField.text stringByReplacingCharactersInRange:range withString:string];
 
 //限制字节数
 if ([inputString length] > 0){
 NSInteger len = strlen([inputString UTF8String]);
 if (len > _maxBytesLength){
  return NO;
 }
 else {
  return YES;
 }
 }
 return YES;
}