如何以编程方式检查 UILabel 是否具有 attributedText 或普通文本?

How to check if UILabel has attributedText or normal text programmatically?

有什么方法可以判断 UILabel 是否使用 label.attributedTextlabel.text 属性 设置了文本?

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

来自apple docs

This property is nil by default. Assigning a new value to this property also replaces the value of the text property with the same string data, albeit without any formatting information. In addition, assigning a new a value updates the values in the font, textColor, and other style-related properties so that they reflect the style information starting at location 0 in the attributed string.

你是对的,检查一个或另一个是否为零是不可能发现的。您可以知道文本已归因的一种方法是使用类似以下内容的方法:

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)]];
}];

这样你就可以看到是否有多个属性。您还可以比较属性是否与您的标准属性匹配,并假设仅在这种情况下设置了文本 属性。

受@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
    }
} 

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

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

这是我想出的实现,逻辑略有改动。这是@Vallette 接受的答案的 Swift 端口,带有额外的保护语句。

只有 return true 如果 attributedText 不为零,不为空,并且至少有一个属性不适用于整个文本范围,该函数才会执行:

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
    }
}

更好的方法是检查 Range 属性的长度是否与字符串的长度相同。如果相同,您可以假设这是 non-attributed 标签。 但是,如果 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
}
    
}