【问题标题】:How to check if UILabel has attributedText or normal text programmatically?如何以编程方式检查 UILabel 是否具有属性文本或普通文本?
【发布时间】:2015-04-03 18:41:17
【问题描述】:

有没有办法判断 UILabel 是否使用label.attributedTextlabel.text 属性设置了文本?

问题是当您设置attributedText 时,text 也会更新,反之亦然,因此无法检查这些属性是否为零。

【问题讨论】:

  • 你想通过解决这个问题来完成什么?
  • 请说明您的意思是以编程方式检查标签是否具有属性文本(如果这实际上是您的意思)。

标签: ios uilabel nsattributedstring


【解决方案1】:

受@lukas-o 的启发,我在UILabel 上编写了一个扩展,以确定它是否包含attributedText。事实上,如果NSAttributedString 不包含任何属性,则此计算属性会将其评估为不具有属性。

extension UILabel {
    var isAttributed: Bool {
        guard let attributedText = attributedText else { return false }
        let range = NSMakeRange(0, attributedText.length)
        var allAttributes = [Dictionary<String, Any>]()
        attributedText.enumerateAttributes(in: range, options: []) { attributes, _, _ in
            allAttributes.append(attributes)
        }
        return allAttributes.count > 1
    }
} 

【讨论】:

  • 在我写完 2 年后查看我自己的答案...为什么我用 &gt; 1 而不是 &gt; 0(或者只使用 return !allAttributes.isEmpty)?您作为读者可以测试isEmpty,很抱歉造成混淆
【解决方案2】:

来自apple docs

此属性默认为 nil。为该属性分配一个新值也会用相同的字符串数据替换 text 属性的值,尽管没有任何格式信息。此外,分配一个新的值会更新字体、textColor 和其他与样式相关的属性中的值,以便它们反映从属性字符串中位置 0 开始的样式信息。

您是对的,不可能通过检查其中一个或另一个是否为 nil。您可以知道文本归属的一种方法是使用以下内容:

NSMutableArray *strAttrs = [NSMutableArray new];
NSMutableArray *strRanges = [NSMutableArray new];

[label.attributedText enumerateAttributesInRange:NSMakeRange(0, label.attributedText.length) options:0 usingBlock:^(NSDictionary *attrs, NSRange range, BOOL *stop) {
        [strAttrs addObject:attrs];
        [strRanges addObject:[NSValue valueWithRange:(range)]];
}];

通过这种方式,您可以查看是否存在多个属性。您还可以比较属性是否与您的标准属性匹配,并假设仅在这种情况下设置了 text 属性。

【讨论】:

    【解决方案3】:

    这是我使用的。如果范围长度等于未归属的文本长度,则该文本只有一个属性,因此是未归属的。

    NSRange range;
    [label.attributedText attributesAtIndex:0 effectiveRange:&range];
    BOOL isAttributed = label.text.length==range.length;
    

    【讨论】:

    • 我觉得最后一行应该是BOOL isAttributed = label.text.length!=range.length
    • 如果attributedText.string 的长度是0,这将崩溃(至少当我将它移植到 swift 时)。我将在下面发布我的实现的更新答案。
    【解决方案4】:

    这是我想出的实现,逻辑略有改变。它是@Vallette 已接受答案的 Swift 端口,带有额外的保护声明。

    如果attributedText 不为零,不为空,并且至少有一个属性不适用于整个文本范围,则该函数只会返回true

    extension UILabel {
    
        var isPartiallyAttributed: Bool {
            guard let attributedText = attributedText else {
                return false
            }
            guard !attributedText.string.isEmpty else {
                return false
            }
            var range = NSRange()
            attributedText.attributes(at: 0, effectiveRange: &range)
            return attributedText.string.count != range.length
        }
    }
    

    【讨论】:

      【解决方案5】:

      更好的方法是检查Range 属性的长度是否与字符串的长度相同。如果相同,您可以假设这是非归属标签。 但是,如果NSAttributes 应用于整个UILabel 文本,我不知道100% 检查属性文本的可靠方法。

      private extension UILabel {
          
          var hasAttributedText: Bool {
          guard let attributedText = attributedText,
                attributedText.string.isEmpty == false else { return false }
          var range = NSRange(location: 0, length: attributedText.length)
          _ = attributedText.attributes(at: 0,
                                        effectiveRange: &range)
          return range.length != attributedText.length
      }
          
      }
      

      【讨论】:

        猜你喜欢
        • 2021-01-21
        • 1970-01-01
        • 2013-06-20
        • 2019-11-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多