确定UILabel中已截断的字符数。

7

我有一个 UILabel,我想确定 UILabel 中截断了多少个字符。
使用下面的代码,如果我的 UILabel 只有 1 行,我可以确定它

int numberOfTruncatedCharacter = 0;
NSString *text = @"Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s";

NSArray  *words = [text componentsSeparatedByString:@" "];
NSString *newStr = @"";
for (NSString *word in words) {
    NSString *statement = [NSString stringWithFormat:@"%@ %@",newStr, word];
    CGSize size = [statement sizeWithAttributes:@{NSFontAttributeName: self.aboutLabel.font}];

    if(size.width < self.aboutLabel.bounds.size.width){
        newStr = [NSString stringWithFormat:@"%@ %@",newStr, word];
    }else{
        numberOfTruncatedCharacter++;
    }
    NSLog(@"%@ | %f | %f",word,size.width,self.aboutLabel.bounds.size.width);
}
NSLog(@"number of truncated character = %d",numberOfTruncatedCharacter);

这个功能正常工作,以下是日志

2016-05-27 10:02:44.642 EarCrush[2284:42690] Lorem | 32.622070 | 355.000000
2016-05-27 10:02:44.642 EarCrush[2284:42690] Ipsum | 64.345703 | 355.000000
2016-05-27 10:02:44.642 EarCrush[2284:42690] is | 74.243164 | 355.000000
2016-05-27 10:02:44.643 EarCrush[2284:42690] simply | 107.138672 | 355.000000
2016-05-27 10:02:44.643 EarCrush[2284:42690] dummy | 145.644531 | 355.000000
2016-05-27 10:02:44.643 EarCrush[2284:42690] text | 165.952148 | 355.000000
2016-05-27 10:02:44.644 EarCrush[2284:42690] of | 177.978516 | 355.000000
2016-05-27 10:02:44.644 EarCrush[2284:42690] the | 195.854492 | 355.000000
2016-05-27 10:02:44.645 EarCrush[2284:42690] printing | 235.004883 | 355.000000
2016-05-27 10:02:44.646 EarCrush[2284:42690] and | 255.429688 | 355.000000
2016-05-27 10:02:44.647 EarCrush[2284:42690] typesetting | 309.921875 | 355.000000
2016-05-27 10:02:44.648 EarCrush[2284:42690] industry. | 353.134766 | 355.000000
2016-05-27 10:02:44.649 EarCrush[2284:42690] Lorem | 385.756836 | 355.000000
2016-05-27 10:02:44.649 EarCrush[2284:42690] Ipsum | 384.858398 | 355.000000
2016-05-27 10:02:44.650 EarCrush[2284:42690] has | 372.202148 | 355.000000
2016-05-27 10:02:44.650 EarCrush[2284:42690] been | 379.218750 | 355.000000
2016-05-27 10:02:44.650 EarCrush[2284:42690] the | 371.010742 | 355.000000
2016-05-27 10:02:44.651 EarCrush[2284:42690] industry's | 401.171875 | 355.000000
2016-05-27 10:02:44.651 EarCrush[2284:42690] standard | 397.431641 | 355.000000
2016-05-27 10:02:44.652 EarCrush[2284:42690] dummy | 391.640625 | 355.000000
2016-05-27 10:02:44.652 EarCrush[2284:42690] text | 373.442383 | 355.000000
2016-05-27 10:02:44.653 EarCrush[2284:42690] ever | 375.844727 | 355.000000
2016-05-27 10:02:44.653 EarCrush[2284:42690] since | 379.541016 | 355.000000
2016-05-27 10:02:44.653 EarCrush[2284:42690] the | 371.010742 | 355.000000
2016-05-27 10:02:44.654 EarCrush[2284:42690] 1500s | 383.374023 | 355.000000
2016-05-27 10:02:44.654 EarCrush[2284:42690] number of truncated character = 13

问题出在我的UILabel有多行时,我更改了代码如下: if(size.width < self.aboutLabel.bounds.size.width * numberOfLines){ 然而它无法正确计算。我认为可能是因为当UILabel有多行时,它会包含换行符。
有什么想法来解决这个问题吗?任何帮助或建议都将不胜感激。

你为什么想知道有多少个字符被截断了呢? - Tomer Even
@KingBabar 我想要将它展示给用户。 - Linh
你能否使用 UITextView 替代 UILabel - Amin Negm-Awad
@PhanVănLinh:你试过我的答案了吗?在我的演示中它运行得很好! - Ketan Parmar
2个回答

1

因为您仅检查了宽度,而忽略了行间距,导致结果不佳。 - Tomer Even

1
你可以这样做,

像这样:

- (void)viewDidLoad {

  [super viewDidLoad];
  UILabel *label1 = self.myLabel;


UIFont *font = label1.font;
NSString *text = @"This is the label text wich will be truncate!!";

CGRect label1Frame = label1.frame;

NSUInteger numberOfCharsInLabel1 = NSNotFound;

NSUInteger numberOfCharactersThatTruncated = NSNotFound;

for (int i = [text length]; i >= 0; i--) {
    NSString *substring = [text substringToIndex:i];
    NSAttributedString *attributedText = [[NSAttributedString alloc] initWithString:substring
                                                                         attributes:@{ NSFontAttributeName : font }];
    CGSize size = CGSizeMake(label1Frame.size.width, CGFLOAT_MAX);
    CGRect textFrame = [attributedText boundingRectWithSize:size
                                                    options:NSStringDrawingUsesLineFragmentOrigin
                                                    context:nil];

    if (CGRectGetHeight(textFrame) <= CGRectGetHeight(label1Frame)) {
        numberOfCharsInLabel1 = i;

        numberOfCharactersThatTruncated = [text length] - numberOfCharsInLabel1;
        break;
    }
}

if (numberOfCharsInLabel1 == NSNotFound) {
    // TODO: Handle this case.
}

 label1.text = [text substringToIndex:numberOfCharsInLabel1];  // If you want to set character that label only can accept without truncating

//OR


label1.text = text;  //set full text with truncating


NSLog(@"Number of Truncated Characters %d",numberOfCharactersThatTruncated);


// Do any additional setup after loading the view.
}

这里的self.myLabel是指标签的出口。 numberOfCharactersThatTruncated是您期望的输出。
这将返回标签中被截断的字符数。
这将完全返回被截断的字符,如果您的字符串是Hello there,并且标签能够显示hell,则结果应该是7,但在标签中看到的是h...,因为标签在截断时显示三个点。因此,如果您想计算根本没有显示的字符,则需要在最终输出中添加3
  numberOfCharactersThatTruncated = numberOfCharactersThatTruncated + 3;

更新:

我的标签框架是: (27,75,93,56)

我刚刚设置了 顶部、前导、固定高度、固定宽度 的约束。

同样的代码非常好用。

我认为你在计算字符数时犯了错误。空格应该被视为一个字符。那么,如果你的标签显示三个点,那么这三个字符的标签就可以显示。

例如:你的字符串是:how are you?

所以总共有12个字符

现在举个例子,你的标签显示:how a...

那么它显示了8个字符(包括.(点))

因此,numberOfCharactersThatTruncated 将返回4。

如果你认为 how a 是唯一可见的字符,而不考虑 .,那么你应该将 3 加到 numberOfCharactersThatTruncated 中。

如果你想只显示适合标签的字符,请使用 label1.text = [text substringToIndex:numberOfCharsInLabel1]; 这个。

它不会显示点号。

Cheers....:)


抱歉回复晚了,因为我的电脑出了问题。我已经检查了你的解决方案,但是如果我的标签有多行,它无法正确计算。 - Linh
你能分享一下你的演示吗?我也创建了一个演示项目并使用了你的代码,但它计算结果不正确。 - Linh
我的演示中没有什么新东西。只是在视图控制器上通过界面构建器放置了一个标签,并取出了它的输出口,还有一个写在答案中的viewDidLoad方法。但我没有为标签设置约束。 - Ketan Parmar
你能否修改你的解决方案,使其与自动布局兼容,然后我可以接受它。现在,当我设计任何布局时,我总是使用自动布局。 - Linh
我已经为我的标签设置了约束条件,同样的代码可以正常工作。请查看我的答案更新。 - Ketan Parmar
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接