Multiline UILabel没有自动换行?

时间:2014-10-16 00:14:40

标签: ios cocoa-touch uilabel textwrapping

是否可以让UILabel由多个\n分隔的行组成,以使其行宽为>标签宽度是否被截断而未被包裹?

假设我有一些如下文字:

  1. 这是一个很长的第一行文字,太长而不能横向放置
  2. 短线
  3. 另一条短线
  4. 我希望它出现在我的UILabel中,如此:

    1. This is a really long first line of text...
    2. Short line
    3. Another short line
    

    然而,正在发生的事情是我得到了这个:

    1. This is a really long first line of text  
    that is too long to fit horizontally
    2. Short line...
    

    第三条线被切断了。我已将行数设置为3,但它仍然包裹第一个长行。我在标签上设置换行符属性似乎并不重要 - 它总是包装第一行。有没有办法防止完全包裹在标签上?

1 个答案:

答案 0 :(得分:3)

我不认为您可以应用于标签的任何设置都可以实现。一种方法是将字符串分成单独的行,截断任何需要它的行,使它(带有一个附加的省略号)适合一行,然后将字符串放回到一起使用换行符。这样的东西应适用于任意数量的行,

@interface ViewController ()
@property (weak, nonatomic) IBOutlet UILabel *label;
@property (nonatomic) CGFloat ellipsisWidth;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    NSString *text = @"This is a really long first line of text that is too long to fit horizontally\nShort line\nAnother short line";
    NSString *ellipsis = @"...";
    self.ellipsisWidth = [ellipsis sizeWithAttributes:@{NSFontAttributeName:self.label.font}].width;

    __block NSMutableString *truncatedString = [@"" mutableCopy];
    [text enumerateLinesUsingBlock:^(NSString *line, BOOL *stop) {
        [truncatedString appendFormat:@"%@\n", [self oneLineOfString:line withFont:self.label.font]];
    }];
    NSString *finalString = [truncatedString stringByTrimmingCharactersInSet:[NSCharacterSet newlineCharacterSet]];
    self.label.numberOfLines = 0;
    self.label.text = finalString;
}

-(NSString *)oneLineOfString:(NSString *) aLine withFont:(UIFont *) font {
    __block NSString *singleLine = nil;
    __block NSString *lastFragment;

    [aLine enumerateSubstringsInRange:NSMakeRange(0, aLine.length) options:NSStringEnumerationByWords usingBlock:^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) {
        NSString *textFragment = [aLine substringToIndex:(substringRange.location + substringRange.length)];
        CGRect textRect = [textFragment boundingRectWithSize:CGSizeMake(CGFLOAT_MAX ,CGFLOAT_MAX) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:font} context:nil];
        if (textRect.size.width >= self.label.bounds.size.width - self.ellipsisWidth) {
            singleLine = [lastFragment stringByAppendingString:@"..."];
            *stop = YES;
        }
        lastFragment = textFragment;
    }];
    if (!singleLine) singleLine = aLine; // it doesn't need to be truncated, so return the passed in line
    return singleLine;
}

如果要按字符而不是按字词截断,可以将NSStringEnumerationByComposedCharacterSequences而不是NSStringEnumerationByWords传递给options参数 enumerateSubstringsInRange:选择:usingBlock:

当然,你可以轻松地做到这一点;将3个标签堆叠在一起,并为每个标签添加一行文字:)