1

我正在尝试减少 NSString 的长度而不用这种方法拆分最后一个单词:

// cut a string by words
- (NSString* )stringCutByWords:(NSString *)string toLength:(int)length;
{
// search backwards in the string for the beginning of the last word
while ([string characterAtIndex:length] != ' ' && length > 0) {
    length--;
}

// if the last word was the first word of the string search for the end of the word
if (length <= 0){
    while ([string characterAtIndex:length] != ' ' && length > string.length-1) {
        length++;
    }
}

// define the range you're interested in
NSRange stringRange = {0, length};

// adjust the range to include dependent chars
stringRange = [string rangeOfComposedCharacterSequencesForRange:stringRange];

// Now you can create the short string
string = [string substringWithRange:stringRange];

return [NSString stringWithFormat:@"%@...",string];
}

现在我的问题是:objective-c 或 cocoa-touch 中是否有我没有看到的内置方式,或者是否有“更好”的方式来做到这一点,因为我对这个解决方案不太满意。

问候和感谢 C4rmel 的帮助

4

2 回答 2

2

我对 Category 方法的建议

@interface NSString (Cut)
-(NSString *)stringByCuttingExceptLastWordWithLength:(NSUInteger)length;
@end


@implementation NSString (Cut)

-(NSString *)stringByCuttingExceptLastWordWithLength:(NSUInteger)length
{
    __block NSMutableString *newString = [NSMutableString string];
    NSArray *components = [self componentsSeparatedByString:@" "];
    if ([components count] > 0) {
        NSString *lastWord = [components objectAtIndex:[components count]-1];

        [components enumerateObjectsUsingBlock:^(NSString *obj, NSUInteger idx, BOOL *stop) {
            if (([obj length]+[newString length] + [lastWord length] + 2) < length) {
                [newString appendFormat:@" %@", obj];
            } else {
                [newString appendString:@"…"];
                [newString appendFormat:@" %@", lastWord];
                *stop = YES;
            }
        }];

    }
    return newString;
}

用法:

NSString *string = @"Hello World! I am standing over here! Can you see me?";
NSLog(@"%@", [string stringByCuttingExceptLastWordWithLength:25]);
于 2012-09-24T21:25:30.453 回答
1

建议:

  1. 使其成为类别方法;
  2. 使用NSCharacterSet和内置的搜索方法,而不是滚动你自己的。

所以:

/* somewhere public */
@interface NSString (CutByWords)
- (NSString *)stringCutByWordsToMaxLength:(int)length
@end

/* in an implementation file, somewhere */

@implementation NSString (CutByWords)

// cut a string by words
- (NSString *)stringCutByWordsToMaxLength:(int)length
{
     NSCharacterSet *whitespaceCharacterSet =
                      [NSCharacterSet whitespaceCharacterSet];

     // to consider: a range check on length here?
     NSRange relevantRange = NSMakeRange(0, length);

     // find beginning of last word
     NSRange lastWordRange =
           [self rangeOfCharacterFromSet:whitespaceCharacterSet
                  options:NSBackwardsSearch
                  range:relevantRange];

     // if the last word was the first word of the string,
     // consume the whole string; this looks to be the same
     // effect as the original scan forward given that the
     // assumption is already made in the scan backwards that
     // the string doesn't end on a whitespace; if I'm wrong
     // then get [whitespaceCharacterSet invertedSet] and do
     // a search forwards
     if(lastWordRange.location == NSNotFound)
     {
          lastWordRange = relevantRange;
     }

    // adjust the range to include dependent chars
    stringRange = [self rangeOfComposedCharacterSequencesForRange:stringRange];

    // Now you can create the short string
    NSString *string = [self substringWithRange:stringRange];

    return [NSString stringWithFormat:@"%@...",string];
}

@end

/* subsequently */

NSString *string = ...whatever...;
NSString *cutString = [string stringCutByWordsToMaxLength:100];
于 2012-09-24T21:07:42.193 回答