2012-09-28 2 views
5

emojis가 포함 된 자체 키보드를 구현하려고합니다. 이 목적으로 이모티콘을 커서 위치에 삽입하고 있습니다.uitextfield positionFromPosition : 오프셋이 작동하지 않습니다. emojis

4 바이트 이모티콘 문자가 UITextField에 없으면 제대로 작동합니다. 그렇지 않으면 앱이 다운됩니다.

여기에 삽입 코드를 게시하고 있습니다. 누군가 문제를 해결하는 방법을 지적 할 수 있습니까?

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을 반환 : 1 개 문자로 4 바이트 문자를 계산 난 내 자신의 길이를 작성하여이 문제를 해결 끝에

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

감사합니다! 이것은 그런 틈새 문제이지만, 그것은 나에게 지옥을 괴롭 히고 있었다. –

답변

4

및 오프셋 계산 방법 두 가지가 아닙니다.

@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

관련 문제