NSString统一处理“常规英文字母”和表情符号,如表情符号或日语

有一个textView,我可以在其中输入字符。 字符可以是a,b,c,d等,或者使用表情符号键盘添加笑脸。

-(void)textFieldDidEndEditing:(UITextField *)textField{ NSLog(@"len:%lu",textField.length); NSLog(@"char:%c",[textField.text characterAtIndex:0]); } 

目前,上述function提供以下输出

 if textField.text = @"qq" len:2 char:q if textField.text = @"😄q" len:3 char:= 

我需要的是

 if textField.text = @"qq" len:2 char:q if textField.text = @"😄q" len:2 char:😄 

有任何线索如何做到这一点?

由于Apple搞砸了表情符号(实际上是超过0的Unicode平面),这变得很困难。 似乎有必要枚举组合字符以获得实际长度。

注意: NSString方法length不返回字符数,而是返回unichars中的代码单元数(不是字符数)。 请参阅NSString和Unicode – Strings – objc.io issue#9 。

示例代码:

 NSString *text = @"qqq😄rrr"; int maxCharacters = 4; __block NSInteger unicharCount = 0; __block NSInteger charCount = 0; [text enumerateSubstringsInRange:NSMakeRange(0, text.length) options:NSStringEnumerationByComposedCharacterSequences usingBlock:^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) { unicharCount += substringRange.length; if (++charCount >= maxCharacters) *stop = YES; }]; NSString *textStart = [text substringToIndex: unicharCount]; NSLog(@"textStart: '%@'", textStart); 

textStart:’qqq😄’

另一种方法是使用utf32编码:

 int byteCount = maxCharacters*4; // 4 utf32 characters char buffer[byteCount]; NSUInteger usedBufferCount; [text getBytes:buffer maxLength:byteCount usedLength:&usedBufferCount encoding:NSUTF32StringEncoding options:0 range:NSMakeRange(0, text.length) remainingRange:NULL]; NSString * textStart = [[NSString alloc] initWithBytes:buffer length:usedBufferCount encoding:NSUTF32LittleEndianStringEncoding]; 

在第128节 – 来自2011 WWDC的高级文本处理中有一些合理性。

这就是我用表情符号字符剪切字符串的方法

 +(NSUInteger)unicodeLength:(NSString*)string{ return [string lengthOfBytesUsingEncoding:NSUTF32StringEncoding]/4; } +(NSString*)unicodeString:(NSString*)string toLenght:(NSUInteger)len{ if (len >= string.length){ return string; } NSInteger charposition = 0; for (int i = 0; i < len; i++){ NSInteger remainingChars = string.length-charposition; if (remainingChars >= 2){ NSString* s = [string substringWithRange:NSMakeRange(charposition,2)]; if ([self unicodeLength:s] == 1){ charposition++; } } charposition++; } return [string substringToIndex:charposition]; }