5

我有一个多行UILabelnumberOfLines= 0)。它的宽度可以在运行时改变,有时这会导致截断和/或重新包装。一些例子最好地说明了这一点:

示例1:宽度的减小导致不同的换行点

在此处输入图像描述 在此处输入图像描述

示例 2:宽度减小导致截断

在此处输入图像描述 在此处输入图像描述

示例 3:宽度的减小导致截断和不同的换行位置

在此处输入图像描述 在此处输入图像描述

示例 4:宽度的减小对截断或换行位置没有任何影响

在此处输入图像描述 在此处输入图像描述

由于格式上的这种变化可能会非常刺耳,我打算将它隐藏在一些动画后面(可能是淡入/淡出)。但是,第一个障碍是确定何时需要这样做。我不想在标签重新调整大小时应用动画 - 只有当它会导致截断或换行位置发生变化时。

我该如何测试这个?测试应返回 YES(例如 1、2 和 3),但返回 NO(例如 4)。

注意:在我的示例中,调整大小永远不会改变行数。

注意 2:如果有人有一些与文本格式相关的更好的标签,我很想知道它们 - 随时编辑。

注意 3:如果您有兴趣看到此行为已完成,请在 iPhone 上尝试 Apple 的 mail.app。查看收件箱时,滑动电子邮件并观看摘要行淡入/淡出,因为它重新换行和/或截断(但不是在不需要时)。

4

5 回答 5

4

斯威夫特 3 解决方案

您可以在分配字符串后计算行数并与标签的最大行数进行比较。

import Foundation
import UIKit

extension UILabel {

    func countLabelLines() -> Int {
        // Call self.layoutIfNeeded() if your view is uses auto layout
        let myText = self.text! as NSString
        let attributes = [NSFontAttributeName : self.font]

        let labelSize = myText.boundingRect(with: CGSize(width: self.bounds.width, height: CGFloat.greatestFiniteMagnitude), options: NSStringDrawingOptions.usesLineFragmentOrigin, attributes: attributes, context: nil)
        return Int(ceil(CGFloat(labelSize.height) / self.font.lineHeight))
    }

    func isTruncated() -> Bool {

        if (self.countLabelLines() > self.numberOfLines) {
            return true
        }
        return false
    }
}
于 2017-03-24T14:31:02.597 回答
2

您可以知道显示特定NSString实例所需的标签大小。例如,您可以使用那个:

- (CGSize)sizeWithFont:(UIFont *)font constrainedToSize:(CGSize)size lineBreakMode:(UILineBreakMode)lineBreakMode

如果使用指定的约束呈现字符串,则返回字符串的大小。

所以你想要的是获取CGSize一个特定的字符串并检查它是否不大于UILabel大小:

    UILabel *label;
    CGSize sizeNeeded = [label.text sizeWithFont:label.font constrainedToSize:CGSizeMake(label.bounds.size.width, MAXFLOAT)];
    if (sizeNeeded.height > label.bounds.size.height)
    {
        NSLog(@"String is truncated");
    }

NSString你可以在这里找到更多有用的方法: NSString UIKit Additions Reference

好的,另一种做你想做的事:

1) 创建UILabel具有相同属性的 2,但第二个 ( label2) 将与另一个具有相同的属性width

2)在非编辑模式下设置to的alpha属性。label20.0

3)当编辑模式开始制作这样的动画:

// label1.alpha == 1.0, label2.alpha == 0.0 
{[UIView animateWithDuration:0.5 animations:^{
    label1.alpha = 0.0;
    label2.alpha = 1.0;
}];

4) 编辑模式结束时:

{[UIView animateWithDuration:0.5 animations:^{
    label1.alpha = 1.0;
    label2.alpha = 0.0;
}];

这将为您提供与 Mail.app 相同的结果

于 2012-10-18T02:05:11.110 回答
1

上面的答案是使用折旧的方法,所以我认为以下代码可能有用:

- (BOOL)isLabelTruncated:(UILabel *)label
{
    BOOL isTruncated = NO;

    CGRect labelSize = [label.text boundingRectWithSize:CGSizeFromString(label.text) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName : label.font} context:nil];

    if (labelSize.size.width / labelSize.size.height > label.numberOfLines) {

        isTruncated = YES;
    }

    return isTruncated;
}
于 2014-04-23T09:02:03.297 回答
1

使用此方法查找 iOS 7 中被截断的标签。

- (BOOL)isTruncated:(UILabel *)label{
        CGSize sizeOfText = [label.text boundingRectWithSize: CGSizeMake(label.bounds.size.width, CGFLOAT_MAX)
                                                     options: (NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading)
                                                  attributes: [NSDictionary dictionaryWithObject:label.font forKey:NSFontAttributeName] context: nil].size;

        if (self.frame.size.height < ceilf(sizeOfText.height)) {
            return YES;
        }
        return NO;
    }
于 2014-07-01T10:39:08.247 回答
0

对于高于 iOS 7 的版本,您可以查看以下解决方案:

  1. https://stackoverflow.com/a/30813691/2123122
  2. https://stackoverflow.com/a/32094824/2123122
于 2015-08-19T12:00:59.730 回答