2012-09-28 38 views
5

Tôi đang cố gắng triển khai bàn phím của riêng mình chứa biểu tượng cảm xúc. Vì mục đích này, tôi đang chèn biểu tượng cảm xúc vào vị trí con trỏ.vị trí uitextfieldTừ vị trí: bù đắp không làm việc biểu tượng cảm xúc

Điều này hoạt động tốt nếu không có ký tự biểu tượng cảm xúc 4 byte tồn tại trong UITextField. Nếu không, ứng dụng sẽ bị lỗi.

Tôi đang đăng mã chèn tại đây. Ai đó có thể chỉ ra cách giải quyết vấn đề này?

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]; 

dòng này trả về nil nếu có biểu tượng cảm xúc trong văn bản:

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

Cảm ơn bạn! Đây là một vấn đề thích hợp, nhưng nó làm tôi khó chịu. –

Trả lời

4

Vào cuối tôi giải quyết điều này bằng cách viết dài của riêng tôi và phương pháp tính toán bù đắp mà đếm ký tự 4-byte như 1 ký tự , không phải hai.

@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 

thấy bài blog đầy đủ http://bit.ly/PT9VSz

2

tôi tìm thấy một cách khác, nó làm việc cho tôi:

- (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

Lưu ý rằng văn bản là văn bản đầy đủ và phạm vi đó là phạm vi của văn bản bạn muốn tìm phạm vi thực. –

+1

@AlexBeals chắc chắn. Có vẻ như tên chức năng của tôi không rõ ràng lắm. Cảm ơn bạn đã mô tả. Hàm cố gắng sửa phạm vi chuỗi đã cho không chia các ký hiệu nhiều ký tự. – k06a

Các vấn đề liên quan