5

絵文字を含む独自のキーボードを実装しようとしています。この目的のために、カーソル位置に絵文字を挿入しています。

UITextFieldに4バイトの絵文字が存在しない場合、これは正常に機能します。そうしないと、アプリがクラッシュします。

ここに挿入コードを掲載しています。誰かが問題を解決する方法を指摘できますか?

UITextField *field = self.textField;
UITextRange *range = field.selectedTextRange;
int pos = [field offsetFromPosition:field.beginningOfDocument toPosition:range.end];
NSString * firstHalfString = [field.text substringToIndex:pos];  
NSString * secondHalfString = [field.text substringFromIndex:pos];  
field.text = [NSString stringWithFormat: @"%@%@%@", firstHalfString, emoticon, secondHalfString];
UITextPosition *newPos = [field positionFromPosition:field.beginningOfDocument offset:pos + 1];
field.selectedTextRange = [field textRangeFromPosition:newPos toPosition:newPos];

テキストに絵文字がある場合、この行はnilを返します。

UITextPosition *newPos = [field positionFromPosition:field.beginningOfDocument offset:pos + 1];
4

2 に答える 2

4

最後に、4バイト文字を2文字ではなく1文字としてカウントする独自の長さとオフセットの計算方法を作成することで、これを解決しました。

@implementation NSString (UnicodeAdditions)
-(NSInteger)utf32length {
    const char* bytes = [self UTF8String];
    int length = [self lengthOfBytesUsingEncoding:NSUTF16StringEncoding];
    int newLength = 0;
    for (int i=0; i<length; i++) {
        if (((unsigned char)bytes[i] >> 7) == 0b00000000)  {
          newLength++;
        }
        else if (((unsigned char)bytes[i] >> 5) == 0b00000110) {
            newLength++;
            i+=1;
        }
        else if (((unsigned char)bytes[i] >> 4) == 0b00001110) {
            newLength++;
            i+=2;
        }
        else if (((unsigned char)bytes[i] >> 3) == 0b00011110) {
            newLength++;
            i+=3;
        }
    }
    return newLength;
}


-(NSInteger)utf32offsetWithOffset:(NSInteger)offset {
    const char* bytes = [self UTF8String];
    int length = [self lengthOfBytesUsingEncoding:NSUTF16StringEncoding];
    int newLength = 0;
    for (int i=0; i<length && offset!=0; i++) {
        if (((unsigned char)bytes[i] >> 7) == 0b00000000)  {
            offset--;
            newLength++;
        }
        else if (((unsigned char)bytes[i] >> 5) == 0b00000110) {
            offset--;
            newLength++;
            i+=1;
        }
        else if (((unsigned char)bytes[i] >> 4) == 0b00001110) {
            offset--;
            newLength++;
            i+=2;
        }
        else if (((unsigned char)bytes[i] >> 3) == 0b00011110) {
            offset-=2;
            newLength++;
            i+=3;
        }
    }
    return newLength;
}

@end

完全なブログ投稿http://bit.ly/PT9VSzを参照してください

于 2012-10-02T03:02:56.210 に答える
2

私は別の方法を見つけました、それは私のために働きます:

- (NSRange)findRealRangeForString:(NSString *)text range:(NSRange)range
{
    __block int loc = 0;
    __block int len = 0;
    [text enumerateSubstringsInRange:NSMakeRange(0, text.length) options:(NSStringEnumerationByComposedCharacterSequences) usingBlock:^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop)
     {
         if (substringRange.location < range.location)
             loc++;
         else if (substringRange.location < range.location + range.length)
             len++;
         else
             *stop = YES; 
     }];
    return NSMakeRange(loc, len);
}
于 2014-01-11T10:49:16.843 に答える