2013-04-02 7 views
9

The Problemकाटना स्ट्रिंग यूनिकोड वर्ण है कि मेरी लंबाई के बीच में स्मैक हो सकता है annihilating बिना शब्द या वर्ण सीमाओं

पर इमोजी या यूनिकोड वर्ण युक्त मैं एक दिया लंबाई में एक स्ट्रिंग को काटना कर सकते हैं कैसे? एक स्ट्रिंग में यूनिकोड चरित्र की शुरुआत की अनुक्रमणिका कैसे निर्धारित कर सकता है ताकि मैं बदसूरत तार बनाने से बच सकूं। एक दृश्य के आधा भाग वाला वर्ग एक अन्य इमोजी चरित्र का स्थान है जिसे छोटा कर दिया गया है।

-(NSMutableAttributedString*)constructStatusAttributedStringWithRange:(CFRange)range 

NSString *original = [_postDictionay objectForKey:@"message"]; 

NSMutableString *truncated = [NSMutableString string]; 

NSArray *components = [original componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; 

for(int x=0; x<[components count]; x++) 
{ 
    //If the truncated string is still shorter then the range desired. (leave space for ...) 
    if([truncated length]+[[components objectAtIndex:x] length]<range.length-3) 
    { 
     //Just checking if its the first word 
     if([truncated length]==0 && x==0) 
     { 
      //start off the string 
      [truncated appendString:[components objectAtIndex:0]]; 
     } 
     else 
     { 
      //append a new word to the string 
      [truncated appendFormat:@" %@",[components objectAtIndex:x]]; 
     } 

    } 
    else 
    { 
     x=[components count]; 
    } 
} 

if([truncated length]==0 || [truncated length]< range.length-20) 
{ 
    truncated = [NSMutableString stringWithString:[original substringWithRange:NSMakeRange(range.location, range.length-3)]]; 
} 

[truncated appendString:@"..."]; 

NSMutableAttributedString *statusString = [[NSMutableAttributedString alloc]initWithString:truncated]; 
[statusString addAttribute:(id)kCTFontAttributeName value:[StyleSingleton streamStatusFont] range:NSMakeRange(0, [statusString length])]; 
[statusString addAttribute:(id)kCTForegroundColorAttributeName value:(id)[StyleSingleton streamStatusColor].CGColor range:NSMakeRange(0, [statusString length])]; 

return statusString; 

} 

अद्यतन जवाब के लिए धन्यवाद, मेरी जरूरतों के लिए एक साधारण समारोह का उपयोग करने में सक्षम था!

-(NSMutableAttributedString*)constructStatusAttributedStringWithRange:(CFRange)range 
{ 
NSString *original = [_postDictionay objectForKey:@"message"]; 

NSMutableString *truncated = [NSMutableString stringWithString:[original substringWithRange:[original rangeOfComposedCharacterSequencesForRange:NSMakeRange(range.location, range.length-3)]]]; 
[truncated appendString:@"..."]; 

NSMutableAttributedString *statusString = [[NSMutableAttributedString alloc]initWithString:truncated]; 
[statusString addAttribute:(id)kCTFontAttributeName value:[StyleSingleton streamStatusFont] range:NSMakeRange(0, [statusString length])]; 
[statusString addAttribute:(id)kCTForegroundColorAttributeName value:(id)[StyleSingleton streamStatusColor].CGColor range:NSMakeRange(0, [statusString length])]; 

return statusString; 

} 

उत्तर

14

NSString एक विधि rangeOfComposedCharacterSequencesForRange है आप उस स्ट्रिंग में संलग्न श्रेणी को ढूंढने के लिए उपयोग कर सकते हैं जिसमें केवल पूर्ण रचना वाले वर्ण हों। उदाहरण के लिए

NSString *s = @""; 
NSRange r = [s rangeOfComposedCharacterSequencesForRange:NSMakeRange(0, 1)]; 

क्योंकि इमोजी पात्र स्ट्रिंग में दो UTF-16 वर्ण (किराए की जोड़ी) के रूप में जमा है, वह सीमा { 0, 2 } देता है।

टिप्पणी: तुम भी आप NSStringEnumerationByWords विकल्प के साथ

enumerateSubstringsInRange:options:usingBlock 

का उपयोग करके अपने पहले पाश को आसान बनाने में कर सकते हैं अगर जांच कर सकता है।

+0

धन्यवाद मार्टिन! –

2

< "एक दिया लंबाई में एक स्ट्रिंग को काटना" - आप वर्णों की संख्या में के रूप में बाइट लंबाई या लंबाई में के रूप में लंबाई मतलब है? यदि उत्तरार्द्ध, तो एक साधारण substringToIndex: पर्याप्त होगा (हालांकि सीमाएं पहले जांचें)। इस प्रकार आपका कोड लिखा जा सकता है:

NSString *TruncateString(NSString *original, NSUInteger maxBytesToRead, NSStringEncoding targetEncoding) { 
    NSMutableString *truncatedString = [NSMutableString string]; 

    NSUInteger bytesRead = 0; 
    NSUInteger charIdx = 0; 

    while (bytesRead < maxBytesToRead && charIdx < [original length]) { 
     NSString *character = [original substringWithRange:NSMakeRange(charIdx++, 1)]; 

     bytesRead += [character lengthOfBytesUsingEncoding:targetEncoding]; 

     if (bytesRead <= maxBytesToRead) 
      [truncatedString appendString:character]; 
    } 

    return truncatedString; 
} 

संपादित करें: पूर्व, तो मुझे डर लग रहा आप की तरह कुछ करना होगा

NSString *original = [_postDictionay objectForKey:@"message"]; 

NSArray *characters = [[original componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]] filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"SELF != ''"]]; 

NSArray *truncatedCharacters = [characters subarrayWithRange:range]; 

NSString *truncated = [NSString stringWithFormat:@"%@...", [truncatedCharacters componentsJoinedByString:@" "]]; 
+0

मैं मूल रूप से substringWithRange का उपयोग कर रहा था, और यह एक बेहतर स्पष्टीकरण की कमी के लिए सचमुच आधे में एक यूनिकोड चरित्र काट देगा। मुझे नहीं पता कि substringToIndex चरित्र को संरक्षित रखेगा। विचार? –

+0

बस substringToIndex को आजमाया, और वही दुर्भाग्यपूर्ण परिणाम थे जैसे substringWithRange –

+0

एचएम ... आप अपना 'एनएसएसटींग' कैसे बना रहे हैं? क्या आप वाकई इसे बनाते समय उचित एन्कोडिंग निर्दिष्ट करते हैं? – fumoboy007

संबंधित मुद्दे