2012-09-28 23 views
5

मैं अपने स्वयं के कीबोर्ड को इमोजीस को लागू करने की कोशिश कर रहा हूं। इस उद्देश्य के लिए मैं कर्सर की स्थिति में इमोजी डाल रहा हूं।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]; 

इस लाइन शून्य अगर वहाँ पाठ में emojis हैं रिटर्न:

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

धन्यवाद! यह एक ऐसी समस्या है, लेकिन यह मेरे बाहर नरक परेशान था। –

उत्तर

4

अंत मैं अपने ही लंबाई लिख कर इस हल पर और ऑफसेट गणना के तरीकों जो 1 चरित्र के रूप में 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