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

时光怂恿深爱的人放手 提交于 2020-04-10 08:11:08

问题


Is there any way to tell if UILabel has its text set using label.attributedText or label.text property?

The problem is when you set attributedText, text is also updated and vice versa, so it is not possible to check these properties for nil.


回答1:


This is what I use. If range length equals the unattributed text length then the text only has a single attribute and is therefore unattributed.

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



回答2:


Inspired by @lukas-o I have written an extension on UILabel that determines if it contains an attributedText or not. In fact if the NSAttributedString does not contain any attributes, this computed property will evaluate it to not be attributed.

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



回答3:


From the 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.

You are right, it's not possible to find that out checking one or the other for nil. One way you could know that the text is attributed would be to use something like:

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

This way you could get see whether more than one attribute is there. You could also compare the attributes whether they match your standard attributes and assume that the text property has been set only in this case.




回答4:


Here is the implementation I came up with, with some slightly altered logic. It is a Swift port of @Vallette 's accepted answer, with additional guard statements.

The function will only return true if the attributedText is not nil, not empty, and has at least one attribute that does not apply across the entire range of the text:

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


来源:https://stackoverflow.com/questions/29437886/how-to-check-if-uilabel-has-attributedtext-or-normal-text-programmatically

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!