【问题标题】:Truncate a string and add ellipsis at the end in Objective-c在 Objective-c 中截断字符串并在末尾添加省略号
【发布时间】:2023-03-27 00:05:01
【问题描述】:

如何在 Objective-C 中截断一个字符串,然后在末尾添加省略号?

【问题讨论】:

  • 截断方式,按字符数或子字符串/分隔符。
  • 字符数,比如100?

标签: iphone objective-c ios


【解决方案1】:
NSString *origString = @"A very long string blah blah blah";
const int clipLength = 18;
if([origString length]>clipLength)
{
    origString = [NSString stringWithFormat:@"%@...",[origString substringToIndex:clipLength]];
}

【讨论】:

  • 这没有考虑边缘情况。您可以在最后一个单词和省略号之间看到一个空格。 (虽然问题没有具体说明行为)
【解决方案2】:

使用这些NSString 方法之一截断,可能是最后一个:

– substringFromIndex:
– substringWithRange:
– substringToIndex:

然后使用NSString方法

– stringByAppendingString:

添加@"..." 或任何你喜欢的省略号。

例如:

NSString *newString = [[string substringToIndex:12] stringByAppendingString:@"..."];

为了您的阅读乐趣,我推荐NSString Class Reference

【讨论】:

  • 该解决方案的问题在于它总是会附加省略号,而只有在执行截断时才应该这样做。
  • 如果 toIndex > [字符串长度],你会得到一个 NSRangeException。下面的答案检查了这一点。
【解决方案3】:

如果您希望截断并将省略号添加到最大为特定宽度的字符串,这里是一个考虑字体和大小的实现:

+ (NSString *)stringByTruncatingString: (NSString *)string toWidth: (CGFloat)width withFont: (UIFont *)font
{
    #define ellipsis @"..."
    NSMutableString *truncatedString = [string mutableCopy];

    if ([string sizeWithAttributes: @{NSFontAttributeName: font}].width > width) {
        width -= [ellipsis sizeWithAttributes: @{NSFontAttributeName: font}].width;

        NSRange range = {truncatedString.length - 1, 1};

        while ([truncatedString sizeWithAttributes: @{NSFontAttributeName: font}].width > width) {
            [truncatedString deleteCharactersInRange:range];
            range.location--;
        }

        [truncatedString replaceCharactersInRange:range withString:ellipsis];
    }

    return truncatedString;
}

【讨论】:

    【解决方案4】:

    执行此操作不需要大量代码.. 最简单的方法,

    对于drawRect

    - (void)drawRect:(NSRect)dirtyRect{
        NSString *theText = @"bla blah bla bhla bla bla";
        NSMutableParagraphStyle *style = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
        [style setLineBreakMode:NSLineBreakByTruncatingTail];
        [theText drawInRect:dirtyRect withAttributes:[NSDictionary dictionaryWithObjectsAndKeys:style, NSParagraphStyleAttributeName,nil]];
    }
    

    听说我使用dirtyRect 作为字符串的绘图区域,您可以随意更改它。

    用于 NSTextField

    NSTextField *_warningTF = [[NSTextField alloc]init];
    [_warningTF setStringValue:@"sfdsf sdfdsfdsfdsfdsfdsfdsf  1234566789123456789sfdsf dsf dsfdsf"];
    [_warningTF.cell setLineBreakMode:NSLineBreakByTruncatingTail];
    

    【讨论】:

      【解决方案5】:

      我写了简单的类别来截断NSString用词

      @interface NSString (TFDString)
      
      - (NSString *)truncateByWordWithLimit:(NSInteger)limit;
      
      
      @end
      
      
      @implementation NSString (TFDString)
      
      - (NSString *)truncateByWordWithLimit:(NSInteger)limit {
          NSRange r = NSMakeRange(0, self.length);
          while (r.length > limit) {
              NSRange r0 = [self rangeOfString:@" " options:NSBackwardsSearch range:r];
              if (!r0.length) break;
              r = NSMakeRange(0, r0.location);
          }
          if (r.length == self.length) return self;
          return [[self substringWithRange:r] stringByAppendingString:@"..."];
      }
      
      
      @end
      

      用法:

      NSString *xx = @"This string is too long, somebody just need to take and truncate it, but by word, please.";
      xx = [xx truncateByWordWithLimit:50];
      

      结果:

      This string is too long, somebody just need to...

      希望它对某人有所帮助。

      【讨论】:

        【解决方案6】:

        drawWithRect:options:attributes:context 方法有帮助。你可以试试这个:

        [_text drawWithRect:_textRect 选项:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingTruncatesLastVisibleLine 属性:属性上下文:nil];

        【讨论】: