【问题标题】:Determine how many characters in UILabel has truncated确定 UILabel 中有多少个字符被截断
【发布时间】:2016-05-27 03:16:32
【问题描述】:

我有一个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 &lt; self.aboutLabel.bounds.size.width * numberOfLines){

但是它不会正确计算。我想也许当UILabel 有多行时,它会包含换行符

任何解决它的想法。任何帮助或建议将不胜感激。

【问题讨论】:

  • 为什么你想知道有多少字符被截断了?
  • @KingBabar 我想展示给用户
  • 您是否可以使用UITextView 而不是UILabel
  • @PhanVănLinh :你试过我的答案了吗?在我的演示中运行良好!

标签: ios objective-c uilabel


【解决方案1】:

您正在检查宽度,但您需要检查高度。

查看此开源代码,了解 TTTAttributedLabel 如何使用 CoreText 了解何时添加“...”字符。

https://github.com/TTTAttributedLabel/TTTAttributedLabel/blob/master/TTTAttributedLabel/TTTAttributedLabel.m

看drawframesetter:attributedstring:textrange:inrect:context:方法

你也可以改开源,暴露'...'的位置

【讨论】:

  • 因为您只检查宽度而忽略了行距,导致结果不佳
【解决方案2】:

你可以这样做,

- (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 是你的desired output

这将返回标签中被截断的字符数。

这将返回完全截断的字符我的意思是如果您的字符串是 Hello there 并且标签能够显示 hell 那么结果应该是 7 但您会在标签中看到类似 h... 因为标签截断时显示三个点。因此,如果您想计算根本不显示的字符,则需要在最终输出中添加3,即

  numberOfCharactersThatTruncated = numberOfCharactersThatTruncated + 3;

更新:

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

我刚刚设置了top,leading,fixed height,fixed width 约束。

同样的代码就像魅力一样工作。

我认为你在数字符时犯了错误。空白应被视为一个字符。然后,如果您的标签显示三个点,则意味着这三个字符标签可以显示。

例如:你的字符串是:你好吗?

所以总字符是:12

现在,例如您的标签显示:如何...

这意味着它显示 8 个字符(包括 .(点))

所以,numberOfCharactersThatTruncated 将返回 4。

如果您认为how a 只是可见字符而不考虑.,那么您应该将3 添加到numberOfCharactersThatTruncated

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

它不会显示点。

干杯....:)

【讨论】:

  • 抱歉,我的电脑有问题,所以回复晚了。我已经检查了您的解决方案,但如果我的标签有多行,则计算不正确
  • 你能分享你的演示吗?我还创建了一个演示项目并使用您的代码,但它计算错误
  • 我的演示中没有新内容。 viewController 上只有一个标签通过界面生成器并从中取出,答案中写有viewDidload。但我没有为标签设置约束。
  • 我正在使用 AutoLayout 所以我需要设置约束
  • 其实我测试的时候并没有设置约束。所以没有约束它应该可以工作!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-04
  • 1970-01-01
  • 2011-06-15
相关资源
最近更新 更多