在特定位置截断UILabel

Eya*_*yal 4 objective-c uilabel ios

我使用表格视图来显示书籍列表,其中每个单元格都有一个UILabel显示书籍名称,另一个UILabel显示书籍的作者

我的问题是关于作者的标签.一本书可以有多个作者,我希望它的行为如下:

  • 如果书中有一位作者('John Colman')的标签应为:"John Colman"
  • 如果书中有多个作者('John Colman','Bob Night','Michael')标签应为:"John Colman +2 authors"

现在的问题是这个,我希望标签在'+'之前被截断.因此,例如,如果第一个作者名称很长,让我们说'Benjamin Walter Jackson',我希望标签看起来像这样:

"Benjamin Walter Ja... +2 authors"
Run Code Online (Sandbox Code Playgroud)

默认行为当然会截断最后的标签,所以它看起来像这样:

"Benjamin Walter Jackson +2 au..."  
Run Code Online (Sandbox Code Playgroud)

如果我使用中间截断,则无法保证它会在正确的位置截断标签(在'+'之前)

我正在寻找一种尽可能高效的方法,而不会影响表格视图的滚动性能.

Sto*_*nz2 5

编辑:广泛使用任何"截断位置"字符串的解决方案.以前的版本仅在字符串实例处截断@" +".编辑允许您定义截断发生的位置.


我从这个问题中得到了答案(这是从本网站上的答案中修改的答案),并根据您的需求量身定制.创建一个新NSString接口,您可以在其中发送字符串以进行自定义截断.

注意:此解决方案仅适用于iOS 7+.要在iOS 6中使用,请使用sizeWithFont:而不是sizeWithAttributes:NSString + TruncateToWidth.m文件中.

的NSString + TruncateToWidth.h

@interface NSString (TruncateToWidth)
- (NSString*)stringByTruncatingAtString:(NSString *)string toWidth:(CGFloat)width withFont:(UIFont *)font;
@end
Run Code Online (Sandbox Code Playgroud)

的NSString + TruncateToWidth.m

#import "NSString+TruncateToWidth.h"

#define ellipsis @"…"

@implementation NSString (TruncateToWidth)

- (NSString*)stringByTruncatingAtString:(NSString *)string toWidth:(CGFloat)width withFont:(UIFont *)font
{
    // If the string is already short enough, or 
    // if the 'truncation location' string doesn't exist
    // go ahead and pass the string back unmodified.
    if ([self sizeWithAttributes:@{NSFontAttributeName:font}].width < width ||
        [self rangeOfString:string].location == NSNotFound)
        return self;

    // Create copy that will be the returned result
    NSMutableString *truncatedString = [self mutableCopy];

    // Accommodate for ellipsis we'll tack on the beginning
    width -= [ellipsis sizeWithAttributes:@{NSFontAttributeName:font}].width;

    // Get range of the passed string. Note that this only works to the first instance found,
    // so if there are multiple, you need to modify your solution
    NSRange range = [truncatedString rangeOfString:string];
    range.length = 1;

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

    // Append ellipsis
    range.length = 0;
    [truncatedString replaceCharactersInRange:range withString:ellipsis];

    return truncatedString;
}

@end
Run Code Online (Sandbox Code Playgroud)

使用它:

// Make sure to import the header file where you want to use it
myLabel.text = [@"Benjamin Walker Jackson + 2 authors" stringByTruncatingAtString:@" +" toWidth:myLabel.frame.size.width withFont:myLabel.font];
// Sample Result: Benjamin Walte... + 2 authors
Run Code Online (Sandbox Code Playgroud)

  • 没关系通过做[truncatedString rangeOfString:@"+"选项:NSBackwardsSearch]来解决它; (2认同)