2012-09-28 81 views
5

我想實現我自己的包含emojis的鍵盤。 爲此,我將光標位置插入表情符號。uitextfield positionFromPosition:偏移量不工作emojis

如果在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]; 

此行返回零,如果有在文本表情符號:

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

謝謝!這是一個小問題,但它讓我非常惱火。 –

回答

4

在我寫我自己的長度解決了這個月底和偏移的計算方法,其計算4個字節的字符作爲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

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); 
} 
+0

請注意,文本是全文,並且該範圍是您想要查找真正範圍的文本的範圍。 –

+1

@AlexBeals肯定。看起來我的功能名稱不是很清楚。感謝您的描述。函數嘗試糾正給定的字符串範圍,不要劃分多字符符號。 – k06a