【问题标题】:NSAttributedString on multiline UILabel cutting off first line多行 UILabel 上的 NSAttributedString 切断第一行
【发布时间】:2014-04-09 21:07:06
【问题描述】:

我已经查看了大约 10 个关于 SO 的问题,但仍然不够完善。

我有一个多行 UILabel(在 Interface Builder 中创建,numberOfLines 设置为 0),通常呈现如下:

我想在“服务条款”和“隐私政策”下划线,所以我添加了以下代码:

NSString *text = self.agreement.text;
NSMutableAttributedString *aString = [[NSMutableAttributedString alloc] initWithString:text];

NSRange privacyRange = [text rangeOfString:@"privacy policy" options:NSCaseInsensitiveSearch];
[aString addAttribute:NSUnderlineStyleAttributeName value:@(NSUnderlineStyleSingle) range:privacyRange];

NSRange tosRange = [text rangeOfString:@"terms of service" options:NSCaseInsensitiveSearch];
[aString addAttribute:NSUnderlineStyleAttributeName value:@(NSUnderlineStyleSingle) range:tosRange];

self.agreement.attributedText = aString;

但是结果是这样的:

我需要怎么做才能显示两条线,并在适当的范围下划线?

另外,我不希望使用 OHAttributedLabel 或 TTTAttributedLabel 之类的第 3 方库,因为这是我的应用程序中唯一需要为一段文本添加下划线的地方。

我的尝试

  • 设置属性文本后调用sizeToFit
  • 改为使用 UITextView。两条线都正确渲染,但我失去了中心对齐。
  • 在代码中重置 numberOfLineslineBreakMode

Sascha 让我上传两张背景颜色设置为非清晰的屏幕截图。奇怪的是,一切都按预期显示!不知道该怎么做或这告诉我们什么。

【问题讨论】:

  • 出于测试目的,为标签指定一个看似比必要更大的高度。第一行还剪掉了吗?
  • 如果我在 IB 中调整高度,运行应用程序时整个标签会消失。如果我在viewDidLoad 的代码中调整标签的框架,我只会得到一行带有两个带下划线的范围。
  • 所有这些奇怪的行为只有在你下划线时才会发生?
  • 由于 Apple 错误(我在 SO 上看到它应该在 7.1 上修复),我建议您现在只使用 2 个单独的 UILabel,这将是最快的解决方案。我也浪费了很多时间..
  • @bilobatum,奇怪的是,如果我将属性字符串设置为不同的颜色而不是下划线,一切都会显示正常。如果一个是颜色,一个是下划线,我只看到一行文本。由于 tsafrir 的建议,也许我会只使用两个标签,或者继续使用颜色更改而不是下划线。

标签: ios objective-c uilabel nsattributedstring nsmutableattributedstring


【解决方案1】:
  1. 首先像你一样创建属性文本:

    NSString *text = self.agreement.text;
    NSMutableAttributedString *aString = [[NSMutableAttributedString alloc] initWithString:text];
    
    NSRange privacyRange = [text rangeOfString:@"privacy policy" options:NSCaseInsensitiveSearch];
    [aString addAttribute:NSUnderlineStyleAttributeName value:@(NSUnderlineStyleSingle) range:privacyRange];
    
    NSRange tosRange = [text rangeOfString:@"terms of service" options:NSCaseInsensitiveSearch];
    [aString addAttribute:NSUnderlineStyleAttributeName value:@(NSUnderlineStyleSingle) range:tosRange];
    
  2. 将您想使用的字体分配给属性字符串:

    [aString addAttribute:NSFontAttributeName value:self.agreement.font range:(NSRange){0, aString.length}];
    
    self.agreement.attributedText = aString;
    
  3. 将您的标签定义为多行:

    self.agreement.numberOfLines = 0;
    self.agreement.lineBreakMode = NSLineBreakByWordWrapping;
    
  4. 估计您的标签尺寸:

    CGRect myLabelRect = [aString boundingRectWithSize:CGSizeMake(self.view.frame.size.width, INT_MAX)
                                               options:NSStringDrawingUsesLineFragmentOrigin
                                               context:nil];
    
  5. 将标签添加到视图时使用估计大小:

    self.agreement.frame = CGRectMake(self.view.frame.size.width / 2 - myLabelRect.size.width / 2,
                                      0,
                                      myLabelRect.size.width,
                                      myLabelRect.size.height);
    [self.view addSubview:self.agreement];
    

【讨论】:

    【解决方案2】:

    所以昨天,基于tsafrir的cmets(iOS 7 bug,应该在7.1修复),我把这两行分成两个标签,继续前进。

    然后,SashaHameister 建议我看看应用不清晰的背景颜色时会发生什么。所以我删除了顶部标签,将文本添加到第二个标签,所以它是两行,更改背景颜色,两行都渲染得很好。我认为这就是解决方案(即使它不起作用,因为我需要清晰的背景)。

    在那之后,我测试了将它改回清除,它仍然对我有用。事实证明,这与我的标签大小有关。我的两行标签的高度约为 75,这对于 11pt 字体的两行标签来说远远超过了必要的高度。由于我昨天所做的调整(将行分成两个标签),当我将第一个标签的文本复制并粘贴到第二个时,高度最终只有 48 像素,并且渲染得很好。

    我仍然不知道为什么会产生如此大的影响,但如果您遇到同样的问题,那么您标签的高度很可能超过了它需要的高度。尝试尽可能减少它,并尽可能紧贴实际文本。

    【讨论】:

    • 这似乎是一个布局问题。你没有使用自动布局?
    • 我目前正在努力解决几乎确切的问题。我尝试调整标签的大小,果然第一行现在被渲染了。多么奇怪的行为!调整大小不是一个完美的解决方案。 UILabel 在UITableViewCell 中。每个单元格都包含唯一的数据。例如,如果我有一个 3 行 UILabel,我可以调整它的大小,以便显示所有 3 行,但如果我表中的下一个单元格只有两行文本,那么第一行将被截断......
    • 我花了几个小时尝试解决并放弃了。我只是将 UILabel 更改为 UITextView 并关闭了编辑和选择的能力。像冠军一样工作
    猜你喜欢
    • 2018-01-26
    • 1970-01-01
    • 1970-01-01
    • 2014-05-04
    • 1970-01-01
    • 2015-11-18
    • 2014-03-04
    • 2014-06-17
    • 1970-01-01
    相关资源
    最近更新 更多